home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 April / EnterCD4.iso / Update / SQL Server SP3 / sql70sp3i.exe / INSTALL / sqldmo.sql < prev    next >
Encoding:
Text File  |  2000-10-24  |  157.9 KB  |  3,843 lines

  1.  
  2. /**********************************************************************
  3.  * Microsoft SQL Server SQL-DMO scripts, version 7.0.
  4.  * Date created:  3/17/96.
  5.  * Date modified: 2/26/97.
  6.  * Copyright Microsoft Corporation, 1992-1997
  7.  **********************************************************************
  8.  *    This script must be installed for the SQL-DMO (SQLDMO) objects and
  9.  *    the SQL Enterprise Manager to run against a Microsoft SQL Server.
  10.  **********************************************************************/
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27. /* Preprocessor directives, will be blank space in output .sql file. */
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34. /* For fetching from cursor */
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84. /* status values for these. */
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92. /* bitmask values for same; power(2, DRI_*). */
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111. /* DRI-generated index masks, to apply to sysindexes.status */
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118. /* sysobjects.category bit that indicates this is an MS-internal object. */
  119.  
  120.  
  121. /* sysobjects.category bit for an sp_ that indicates it's a startup proc, or an xp that should ImpersonateClient. */
  122.  
  123.  
  124.  
  125. /* BIT_CLUSTERED indicates the key is clustered. */
  126. /* EXCLUDE REPLICATION value in sysconstraints.status, and system-generated name. */
  127.  
  128.  
  129.  
  130.  
  131.  
  132. /* sysobjects.sysstat bits (lower 4) that mask off the object type. */
  133.  
  134.  
  135. /* bit for DEFAULTS which are really DRI-created. */
  136.  
  137.  
  138. /* bits for sp_MShelpcolumns col_flags - don't conflict with bit_sysgenname for DRIDefaults. */
  139.  
  140.  
  141.  
  142.  
  143.  
  144. /* sysdatabases.category bits */
  145.  
  146.  
  147.  
  148. /* sysobjects.category bits (from ntdbms\object.h) */
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166. /* The parser can't '|' 0x-prefixed types as it thinks they're binary */
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174. /**** daVinci additions ****/
  175.  
  176. /* sp_MStablekeys @flags bitmask param values. */
  177.  
  178.  
  179. /* sp_MShelpindexes @flags bitmask param values. */
  180.  
  181.  
  182. /* sp_MStablechecks @flags bitmask param values. */
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189. /* Internal #defines for SQLDMO. */
  190.  
  191. /* Current SQLDMO version.  Also must be available to SQLDMO.odl. */
  192.  
  193.  
  194.  
  195. /* Make sure we use our own; shield SQLDMO from Starfighter changes. */
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203. /* Our max name lengths. */
  204. /* !! All lengths retrieved from server must be rounded UP TO THE NEXT 4-bytes. !! */
  205. /* There must be at least one byte more than server max length, for the NULL byte. */
  206.  
  207. /* 7.0 Identifier length has been increased from 30 to 128 characters */
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /* Keep for Replication, but changed to SYSNAME length */
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. /* 7.0 */
  259.  
  260.  
  261.  
  262. /* Reserve enough space for [] quoting character, and escape character in identifier */
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283. /* Specail Identifier length for mapping table when scripting from 6.x server, this is the sysname length for 6.x server */
  284.  
  285.  
  286.  
  287.  
  288.  
  289. use master
  290. go
  291.  
  292. print ''
  293. print 'Creating SQLDMO stored procedures...'
  294. print ''
  295.  
  296. /************* DUMP THE TRANSACTION LOG **************************************/
  297. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  298. /* script periodically, you will run out of transaction log space.           */
  299. print ''
  300. print 'Dumping transaction log...'
  301. print ''
  302. go
  303. dump tran master with no_log
  304. go
  305. /************* END DUMP THE TRANSACTION LOG **********************************/
  306.  
  307. /********************** Include individual components definitions *********************************/
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360. /* From perm.h */
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375. /* Roles */
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394. /* File Growth */
  395.  
  396.  
  397. /* Max. Column length */
  398.  
  399.  
  400.  
  401. /********************* Delete existing objects *********************************/
  402. print N''
  403. print N'Deleting existing objects...'
  404. print N''
  405. go
  406.  
  407. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpcolumns')
  408.     drop procedure sp_MShelpcolumns
  409. go
  410. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpindex')
  411.     drop procedure sp_MShelpindex
  412. go
  413. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelptype')
  414.     drop procedure sp_MShelptype
  415. go
  416. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdependencies')
  417.     drop procedure sp_MSdependencies
  418. go
  419. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablespace')
  420.     drop procedure sp_MStablespace
  421. go
  422. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSindexspace')
  423.     drop procedure sp_MSindexspace
  424. go
  425. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSuniquename')
  426.     drop procedure sp_MSuniquename
  427. go
  428. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSkilldb')
  429.     drop procedure sp_MSkilldb
  430. go
  431. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSobjectprivs')
  432.     drop procedure sp_MSobjectprivs
  433. go
  434. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSloginmappings')
  435.     drop procedure sp_MSloginmappings
  436. go
  437. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablekeys')
  438.     drop procedure sp_MStablekeys
  439. go
  440. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablechecks')
  441.     drop procedure sp_MStablechecks
  442. go
  443. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablerefs')
  444.     drop procedure sp_MStablerefs
  445. go
  446. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSsettopology')
  447.     drop procedure sp_MSsettopology
  448. go
  449. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSmatchkey')
  450.     drop procedure sp_MSmatchkey
  451. go
  452. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeachdb')
  453.     drop procedure sp_MSforeachdb
  454. go
  455. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeachtable')
  456.     drop procedure sp_MSforeachtable
  457. go
  458. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeach_worker')
  459.     drop procedure sp_MSforeach_worker
  460. go
  461. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLOLE_version')
  462.     drop procedure sp_MSSQLOLE_version
  463. go
  464. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLOLE65_version')
  465.     drop procedure sp_MSSQLOLE65_version
  466. go
  467. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLDMO70_version')
  468.     drop procedure sp_MSSQLDMO70_version
  469. go
  470. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSscriptdatabase')
  471.     drop procedure sp_MSscriptdatabase
  472. go
  473. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSscriptdb_worker')
  474.     drop procedure sp_MSscriptdb_worker
  475. go
  476. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdbuseraccess')
  477.     drop procedure sp_MSdbuseraccess
  478. go
  479. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdbuserpriv')
  480.     drop procedure sp_MSdbuserpriv
  481. go
  482. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpfulltextindex')
  483.     drop procedure sp_MShelpfulltextindex
  484. go
  485. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpfulltextscript')
  486.     drop procedure sp_MShelpfulltextscript
  487. go
  488. /* sp_MSqv have been removed, but we want to keep this query, just in case there are left over from previous build */
  489. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSqv')
  490.     drop procedure sp_MSqv
  491. go
  492.  
  493.  
  494. /********************* Create new objects *********************************/
  495.  
  496. /* New validation added for 7.0 */
  497. /* if (@@microsoftversion >= SQL70_MINVERSION) begin                                       */
  498. /*     exec sp_MS_upd_sysobj_category 1                                                       */
  499. /* end else begin                                                                          */
  500. /*     RAISERROR 55555 'You need a released version of SQL 7.0 to run this SQLDMO script'     */
  501. /* end                                                                                     */
  502. if (@@microsoftversion < 0x07000000) begin
  503.     RAISERROR 55555 N'You need a released version of SQL 7.0 to run this SQLDMO script'
  504. end
  505.  
  506. /*******************************************************************************/
  507. print N''
  508. print N'Creating sp_MShelpcolumns'
  509. print N''
  510. go
  511. create procedure sp_MShelpcolumns
  512. @tablename nvarchar(517), @flags int = 0, @orderby nvarchar(10) = null, @flags2 int = 0
  513. as
  514.  
  515.    /* For non-string columns, sp_MShelpcolumns returns the length in syscolumns.length, */
  516.    /* which is defined in BOL as "maximum physical storage length from systypes".       */
  517.    /* For string columns (including types based on string types), sp_MShelpcolumns      */
  518.    /* returns this maximum length in characters (i.e. it returns syscolumns.length      */
  519.    /* adjusted to whether the column is based on char or nchar).                        */
  520.  
  521.    /*** @flags2 added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  522.    /*** sp_MShelpcolumns '%s', null, 'id', 1                           ***/
  523.  
  524. /** For DaVinci **/
  525. /** Use sp_help filtering of precision/scale (only fordecimal/numeric types; else use NULL). **/
  526.  
  527.  
  528.     if @flags is null
  529.         select @flags = 0
  530.     if (@tablename = N'?')
  531.     begin
  532.         print N''
  533.         print N'Usage:  sp_MShelpcolumns @tablename, @flags int = 0'
  534.         print N' where @flags is a bitmask of:'
  535.         print N' 0x0200        = No DRI (ignore Checks, Primary/Foreign/Unique Keys, etc.)'
  536.         print N' 0x0400        = UDDTs --> Base type'
  537.         print N' 0x80000        = TimestampToBinary (convert timestamp cols to binary(8))'
  538.         print N' 0x40000000    = No Identity attribute'
  539.         return 0
  540.     end
  541.  
  542.     declare @objid int
  543.     select @objid = object_id(@tablename)
  544.     if (@objid is null)
  545.     begin
  546.         RAISERROR (15001, -1, -1, @tablename)
  547.         return 1
  548.     end
  549.  
  550.     set nocount on
  551.  
  552.     create table #sphelpcols
  553.     (
  554.        col_name            nvarchar(128)            NOT NULL,
  555.        col_id            int                    NOT NULL,
  556.        col_typename        nvarchar(128)            NOT NULL,
  557.        col_len            int                    NOT NULL,
  558.        col_prec            int                    NULL,
  559.        col_scale        int                    NULL,
  560.        col_numtype        smallint            NOT NULL,    /* For DaVinci to get sp_help-type filtering of prec/scale */
  561.        col_null            bit                    NOT NULL,    /* status & 8 */
  562.        col_identity        bit                    NOT NULL,    /* status & 128 */
  563.        col_defname        nvarchar(257)            NULL,        /* fully-qual'd default name, or NULL */
  564.        col_rulname        nvarchar(257)            NULL,        /* fully-qual'd rule name, or NULL */
  565.        col_basetypename    nvarchar(128)            NOT NULL,
  566.        col_flags        int                    NULL,        /* COL_* bits */
  567.        col_seed            numeric (28)      NULL,
  568.        col_increment    int                 NULL,
  569.        col_dridefname    nvarchar(128)            NULL,        /* DRI DEFAULT name */
  570.        col_dridefid    int                    NULL,         /* remember the DRI DEFAULT id in syscomments, so we can retrieve it later */
  571.       col_iscomputed int               NOT NULL,
  572.        col_objectid    int                    NOT NULL,     /* column object id, need it to get computed text from syscomments */
  573.        col_NotForRepl    bit                    NOT NULL,     /* Not For Replication setting */
  574.        col_fulltext    bit                    NOT NULL,     /* FullTextIndex setting */
  575.        col_AnsiPad     bit               NULL,         /* Ansi_Padding setting */
  576.       /* following columns are repeating the info from col_defname and col_rulname                  */
  577.       /* because we can not change data in col_defname and col_rulname, since daVinci is using them */
  578.        col_DOwner     nvarchar(128)            NULL,        /* non-DRI DEFAULT owner, or NULL */
  579.        col_DName      nvarchar(128)            NULL,        /* non-DRI DEFAULT name, or NULL */
  580.        col_ROwner     nvarchar(128)            NULL,        /* non-DRI RULE owner, or NULL */
  581.        col_RName      nvarchar(128)            NULL,        /* non-DRI RULE name, or NULL */
  582.     )
  583.  
  584.    /* Do not store the computed text in this temp table, because one extra join causes big performance hit */
  585.     /* First load stuff so we can blot off inappropriate info and massage as per @flags */
  586.     insert #sphelpcols
  587.         select c.name, c.colid, st.name,
  588.          case when bt.name in (N'nchar', N'nvarchar') then c.length/2 else c.length end,
  589.             ColumnProperty(@objid, c.name, N'Precision'),
  590.             ColumnProperty(@objid, c.name, N'Scale'),
  591.                 -- col_numtype for DaVinci:  use sp_help-type prec/scale filtering for @flags2 & 1
  592.             case when (@flags2 & 1 <> 0 and bt.name in (N'tinyint',N'smallint',N'decimal',N'int',N'real',N'money',N'float',N'numeric',N'smallmoney'))
  593.                     then 1 else 0 end,
  594.                 -- Nullable
  595.             convert(bit, ColumnProperty(@objid, c.name, N'AllowsNull')),
  596.                 -- Identity
  597.             case when (@flags & 0x40000000 = 0) then convert(bit, ColumnProperty(@objid, c.name, N'IsIdentity')) else 0 end,
  598.                 -- Non-DRI Default (make sure it's not a DRI constraint).
  599.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else user_name(d.uid) + N'.' + d.name end,
  600.                 -- Non-DRI Rule
  601.             case when (c.domain = 0) then null else user_name(r.uid) + N'.' + r.name end,
  602.                 -- Physical base datatype
  603.             bt.name,
  604.                 -- Initialize flags to whether it's a length-specifiable type, or a numeric type, or 0.
  605.             case when st.name in (N'char',N'varchar',N'binary',N'varbinary',N'nchar',N'nvarchar') then 0x0001
  606.                     when st.name in (N'decimal',N'numeric') then 0x0002
  607.                     else 0 end
  608.                     -- Will be NULL if column is not UniqueIdentifier.
  609.                     + case isnull(ColumnProperty(@objid, c.name, N'IsRowGuidCol'), 0) when 0 then 0 else 0x0008 end,
  610.                 -- Identity seed and increment
  611.             case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then ident_seed(@tablename) else null end,
  612.             case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then ident_incr(@tablename) else null end,
  613.                 -- DRI Default name
  614.             case when (@flags & 0x0200 = 0 and c.cdefault is not null and (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0))
  615.                     then object_name(c.cdefault) else null end,
  616.                 -- DRI Default text, if it does not span multiple rows (if it does, SQLDMO will go get them all).
  617.             case when (@flags & 0x0200 = 0 and c.cdefault is not null and (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0))
  618.                     then t.id else null end,
  619.          c.iscomputed,
  620.          c.id,
  621.                 -- Not For Replication
  622.             convert(bit, ColumnProperty(@objid, c.name, N'IsIdNotForRepl')),
  623.          convert(bit, ColumnProperty(@objid, c.name, N'IsFulltextIndexed')),
  624.          convert(bit, ColumnProperty(@objid, c.name, N'UsesAnsiTrim')),
  625.                 -- Non-DRI Default owner and name
  626.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else user_name(d.uid) end,
  627.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else d.name end,
  628.                 -- Non-DRI Rule owner and name
  629.             case when (c.domain = 0) then null else user_name(r.uid) end,
  630.             case when (c.domain = 0) then null else r.name end
  631.         from syscolumns c
  632.                 -- NonDRI Default and Rule filters
  633.             left outer join sysobjects d on d.id = c.cdefault
  634.             left outer join sysobjects r on r.id = c.domain
  635.                 -- Fully derived data type name
  636.             join systypes st on st.xusertype = c.xusertype
  637.                 -- Physical base data type name
  638.             join systypes bt on bt.xusertype = c.xtype
  639.                 -- DRIDefault text, if it's only one row.
  640.             left outer join syscomments t on t.id = c.cdefault and t.colid = 1
  641.                     and not exists (select * from syscomments where id = c.cdefault and colid = 2)
  642.         where c.id = @objid
  643.         order by c.colid
  644.  
  645.     /* Convert any timestamp column to binary(8) if they asked. */
  646.     if (@flags & 0x80000 != 0)
  647.         update #sphelpcols set col_typename = N'binary', col_len = 8, col_flags = col_flags | 0x0001 where col_typename = N'timestamp'
  648.  
  649.     /* Now see what our flags are, if anything. */
  650.     if (@flags is not null and @flags != 0)
  651.     begin
  652.         if (@flags & 0x0400 != 0)
  653.         begin
  654.             /* Track from xusertype --> b.<base>xtype --> u.xusertype in systypes */
  655.             /* First mask off the things we will set.  The convert() awkwardness is */
  656.             /* necessitated by SQLServer's handling of 0x-prefixed values. */
  657.             declare @typeflagmask int select @typeflagmask = (convert(int, 0x0001) + convert(int, 0x0002))
  658.             update #sphelpcols set col_typename = b.name,
  659.                 -- ReInitialize flags to whether it's a length-specifiable type, or a numeric type, or 0.
  660.                 col_flags = col_flags & ~@typeflagmask
  661.                             + case when b.name in (N'char',N'varchar',N'binary',N'varbinary',N'nchar',N'nvarchar') then 0x0001
  662.                                 when b.name in (N'decimal',N'numeric') then 0x0002
  663.                                 else 0 end
  664.             from #sphelpcols c, systypes n, systypes b
  665.                 where n.name = col_typename                --// xtype (base type) of name
  666.                     and b.xusertype = n.xtype            --// Map it back to where it's xusertype, to get the name
  667.         end
  668.     end
  669.  
  670.     /* Determine if the column is in the primary key */
  671.     if (@flags & 0x0200 = 0 and (OBJECTPROPERTY(@objid, N'TableHasPrimaryKey') <> 0)) begin
  672.         declare @indid int
  673.         select @indid = indid from sysindexes i where i.id = @objid and i.status & 0x0800 <> 0
  674.         if (@indid is not null)
  675.             update #sphelpcols set col_flags = col_flags | 0x0004
  676.             from #sphelpcols c, sysindexkeys i
  677.                 where i.id = @objid and i.indid = @indid and i.colid = c.col_id
  678.     end
  679.  
  680.     /* OK, now put out the data.  @flags2 added for DaVinci; currently only bit 1 (sp_help filtering of prec/scale) is relevant. */
  681.     set nocount off
  682.     if (@orderby is null or @orderby = N'id')
  683.     begin
  684.         select c.col_name, c.col_id, c.col_typename, c.col_len,
  685.                     -- Prec/scale only for numeric/decimal
  686.                 col_prec = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  687.                         then c.col_prec else NULL end,
  688.                 col_scale = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  689.                         then c.col_scale else NULL end,
  690.                 col_basetypename, c.col_defname, c.col_rulname, c.col_null, c.col_identity, c.col_flags,
  691.                c.col_seed,
  692.             c.col_increment, c.col_dridefname, cn.text, c.col_iscomputed, cm.text, c.col_NotForRepl,
  693.             c.col_fulltext, c.col_AnsiPad, c.col_DOwner, c.col_DName, c.col_ROwner, c.col_RName
  694.         from (#sphelpcols c
  695.       left outer join syscomments cm on cm.id = c.col_objectid and cm.number = c.col_id) left outer join syscomments cn on c.col_dridefid is not null and cn.id = c.col_dridefid
  696.         order by c.col_id
  697.     end else begin
  698.         select c.col_name, c.col_id, c.col_typename, c.col_len,
  699.                     -- Prec/scale only for numeric/decimal
  700.                 col_prec = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  701.                         then c.col_prec else NULL end,
  702.                 col_scale = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  703.                         then c.col_scale else NULL end,
  704.                 col_basetypename, c.col_defname, c.col_rulname, c.col_null, c.col_identity, c.col_flags,
  705.                c.col_seed,
  706.             c.col_increment, c.col_dridefname, cn.text, c.col_iscomputed, cm.text, c.col_NotForRepl,
  707.             c.col_fulltext, c.col_AnsiPad, c.col_DOwner, c.col_DName, c.col_ROwner, c.col_RName
  708.         from (#sphelpcols c
  709.       left outer join syscomments cm on cm.id = c.col_objectid and cm.number = c.col_id) left outer join syscomments cn on c.col_dridefid is not null and cn.id = c.col_dridefid
  710.         order by c.col_name
  711.     end
  712.  
  713. go
  714. /* End sp_MShelpcolumns */
  715.  
  716. /*******************************************************************************/
  717. print N''
  718. print N'Creating sp_MShelpindex'
  719. print N''
  720. go
  721. create procedure sp_MShelpindex
  722. @tablename nvarchar(517), @indexname nvarchar(258) = null, @flags int = null
  723. as
  724.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  725.    /*** sp_MShelpindex '%s', null, 1                                  ***/
  726.  
  727.    /* @flags is for daVinci */
  728.    if (@flags is null)
  729.       select @flags = 0
  730.    if (@flags <> 0)
  731.    begin
  732.    /* daVinci is calling */
  733.       select i.name, i.status, i.indid, i.OrigFillFactor,
  734.       IndCol1 = index_col(@tablename, i.indid, 1),
  735.       IndCol2 = index_col(@tablename, i.indid, 2),
  736.       IndCol3 = index_col(@tablename, i.indid, 3),
  737.       IndCol4 = index_col(@tablename, i.indid, 4),
  738.       IndCol5 = index_col(@tablename, i.indid, 5),
  739.       IndCol6 = index_col(@tablename, i.indid, 6),
  740.       IndCol7 = index_col(@tablename, i.indid, 7),
  741.       IndCol8 = index_col(@tablename, i.indid, 8),
  742.       IndCol9 = index_col(@tablename, i.indid, 9),
  743.       IndCol10 = index_col(@tablename, i.indid, 10),
  744.       IndCol11 = index_col(@tablename, i.indid, 11),
  745.       IndCol12 = index_col(@tablename, i.indid, 12),
  746.       IndCol13 = index_col(@tablename, i.indid, 13),
  747.       IndCol14 = index_col(@tablename, i.indid, 14),
  748.       IndCol15 = index_col(@tablename, i.indid, 15),
  749.       IndCol16 = index_col(@tablename, i.indid, 16)
  750.       , SegName = s.groupname
  751.       , FullTextKey = IndexProperty(object_id(@tablename), i.name, N'IsFulltextKey')
  752.       from (sysindexes i inner join
  753.          sysfilegroups s on
  754.          i.groupid = s.groupid )
  755.       where id = object_id(@tablename) and i.indid > 0 and i.indid < 255 and
  756.       (@indexname is null or i.name = @indexname) and
  757.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsStatistics') <> 1) and
  758.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsAutoStatistics') <> 1) and
  759.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsHypothetical') <> 1)
  760.       order by i.indid
  761.    end else begin
  762.       /* select (case when (i.status & 0x0040) != 0 then substring(i.name, 9, (datalength(i.name)/2)-17) else i.name end), i.status, i.indid, i.OrigFillFactor, */
  763.       select i.name, i.status, i.indid, i.OrigFillFactor,
  764.       IndCol1 = index_col(@tablename, i.indid, 1),
  765.       IndCol2 = index_col(@tablename, i.indid, 2),
  766.       IndCol3 = index_col(@tablename, i.indid, 3),
  767.       IndCol4 = index_col(@tablename, i.indid, 4),
  768.       IndCol5 = index_col(@tablename, i.indid, 5),
  769.       IndCol6 = index_col(@tablename, i.indid, 6),
  770.       IndCol7 = index_col(@tablename, i.indid, 7),
  771.       IndCol8 = index_col(@tablename, i.indid, 8),
  772.       IndCol9 = index_col(@tablename, i.indid, 9),
  773.       IndCol10 = index_col(@tablename, i.indid, 10),
  774.       IndCol11 = index_col(@tablename, i.indid, 11),
  775.       IndCol12 = index_col(@tablename, i.indid, 12),
  776.       IndCol13 = index_col(@tablename, i.indid, 13),
  777.       IndCol14 = index_col(@tablename, i.indid, 14),
  778.       IndCol15 = index_col(@tablename, i.indid, 15),
  779.       IndCol16 = index_col(@tablename, i.indid, 16)
  780.       , SegName = s.groupname
  781.       , FullTextKey = IndexProperty(object_id(@tablename), i.name, N'IsFulltextKey')
  782.       from (sysindexes i inner join
  783.          sysfilegroups s on
  784.          i.groupid = s.groupid )
  785.       where id = object_id(@tablename) and i.indid > 0 and i.indid < 255
  786.       and (@indexname is null or i.name = @indexname)
  787.       order by i.indid
  788.       /* order by i.name */
  789.    end
  790.  
  791. go
  792. /* End sp_MShelpindex */
  793.  
  794. /************* DUMP THE TRANSACTION LOG **************************************/
  795. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  796. /* script periodically, you will run out of transaction log space.           */
  797. print N''
  798. print N'Dumping transaction log...'
  799. print N''
  800. go
  801. dump tran master with no_log
  802. go
  803. /************* END DUMP THE TRANSACTION LOG **********************************/
  804.  
  805. /*******************************************************************************/
  806. print N''
  807. print N'Creating sp_MShelptype'
  808. print N''
  809. go
  810. create procedure sp_MShelptype
  811. @typename nvarchar(517) = null, @flags nvarchar(10) = null
  812. as
  813.     if (@typename = N'?')
  814.     begin
  815.         print N''
  816.         print N'Usage:  sp_MShelptype @typeename = null, @flags nvarchar(10) = null'
  817.         print N' where @flags is either:'
  818.         print N' sdt        = look in system datatypes'
  819.         print N' uddt      = look in user defined datatypes'
  820.         print N' null    = look wherever its found'
  821.         print N''
  822.         return 0
  823.     end
  824.  
  825.     /* Catch typos... */
  826.     if (@flags is not null and @flags not in (N'sdt', N'uddt'))
  827.         select @flags = null
  828.  
  829.     /* Find out what type we're gonna be looking in, if they gave us a name. */
  830.     if (@typename is not null)
  831.     begin
  832.         declare @xusertype int
  833.         select @xusertype = xusertype from systypes where name = @typename
  834.         if (@xusertype is not null)
  835.         begin
  836.             if (@xusertype < 257)
  837.             begin
  838.                 if (@flags is null)
  839.                     select @flags = N'sdt'
  840.                 if (@flags != N'sdt')
  841.                     select @xusertype = null
  842.             end else begin
  843.                 if (@flags is null)
  844.                     select @flags = N'uddt'
  845.                 if (@flags != N'uddt')
  846.                     select @xusertype = null
  847.             end
  848.         end
  849.         if (@xusertype is null)
  850.         begin
  851.             RAISERROR (15001, -1, -1, @typename)
  852.             return 1
  853.         end
  854.     end
  855.  
  856.     /* Now go get the info, depending on the type they gave us. */
  857.     if (@flags is null or @flags = N'sdt')
  858.     begin
  859.         /* Exclude the 'xxxxn' dblib-specific nullable types, and hardcode a check for variable length and numeric usertypes. */
  860.       /* 7.0 ifvarlen_max returns length for all the datatypes */
  861.         select     SystemDatatypeName = t.name,
  862.                 ifvarlen_max = y.length,
  863.                     -- timestamp allows nulls even though the system tables say it doesn't.
  864.                 allownulls = case when t.name in (N'timestamp') then 1 else t.allownulls end,
  865.                 isnumeric = case when t.name in (N'decimal', N'numeric') then 1 else 0 end,
  866.                 allowidentity = case when t.name in (N'decimal', N'int', N'numeric', N'smallint', N'tinyint') then 1 else 0 end,
  867.             variablelength = t.variable,
  868.             max_len = t.length, prec_len = t.prec
  869.          from systypes t, systypes y
  870.          where t.xusertype < 257 and t.name not in (N'datetimn', N'decimaln', N'floatn', N'intn', N'moneyn', N'numericn') and (@typename is null or t.name = @typename)
  871.          and y.xusertype =* t.xusertype and y.name in ( N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar' )
  872.             order by t.name
  873.     end
  874.  
  875.     /* Need a temp table so we can ownerqualify nonNULL rules/defaults. */
  876.     create table #sphelptype (
  877.         dt_xusertype        int                NULL,
  878.         dt_basetype        nvarchar(128)    NULL,
  879.         dt_rul             int                NULL,
  880.         dt_def             int                NULL,
  881.  
  882.         dt_rulowner        nvarchar(128)        NULL,
  883.         dt_rulname         nvarchar(128)        NULL,
  884.         dt_defowner        nvarchar(128)        NULL,
  885.         dt_defname        nvarchar(128)        NULL,
  886.         dt_flags        int                NULL
  887.     )
  888.  
  889.     if (@flags is null or @flags = N'uddt')
  890.     begin
  891.         set nocount on
  892.         insert #sphelptype (dt_xusertype, dt_basetype, dt_rul, dt_def, dt_flags)
  893.             select t.xusertype,
  894.             (select distinct b.name from systypes b where b.xtype = t.xtype and b.xusertype < 257 and b.name not in (N'sysname', N'timestamp')),
  895.             t.domain, t.tdefault, 0
  896.             from systypes t
  897.             where t.xusertype > 256 and (@typename is null or t.name = @typename)
  898.  
  899.         /* Make a nice, presentable qualified rule/default name for those which are non-null */
  900.       update #sphelptype set dt_defowner = user_name(d.uid)
  901.             from #sphelptype c, sysobjects d where c.dt_def is not null and d.id = c.dt_def
  902.       update #sphelptype set dt_defname = d.name
  903.             from #sphelptype c, sysobjects d where c.dt_def is not null and d.id = c.dt_def
  904.  
  905.       update #sphelptype set dt_rulowner = user_name(r.uid)
  906.             from #sphelptype c, sysobjects r where c.dt_rul is not null and r.id = c.dt_rul
  907.       update #sphelptype set dt_rulname =  r.name
  908.             from #sphelptype c, sysobjects r where c.dt_rul is not null and r.id = c.dt_rul
  909.  
  910.         /* For scripting, set the dt_flags -- these apply to the BASE datatype. */
  911.         update #sphelptype set dt_flags = dt_flags | 0x0001 where dt_basetype in ( N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar')
  912.         update #sphelptype set dt_flags = dt_flags | 0x0002 where dt_basetype in (N'numeric', N'decimal')
  913.  
  914.         set nocount off
  915.         select distinct UserDatatypeName = t.name,
  916.                 owner = user_name(t.uid),
  917.                 basetypename = (select distinct b.name from systypes b where b.name = s.dt_basetype),
  918.                 defaultname = dt_defname,
  919.                 rulename = dt_rulname,
  920.                 tid = t.xusertype,
  921.                 length = case when s.dt_basetype in (N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar') then t.length else 0 end,
  922.                 nullable = t.allownulls,
  923.                 dt_prec = case when s.dt_basetype in (N'numeric', N'decimal') then t.prec else null end,
  924.                 dt_scale = case when s.dt_basetype in (N'numeric', N'decimal') then t.scale else null end,
  925.                 dt_flags,
  926.                 allowidentity = case when (s.dt_basetype in (N'decimal', N'int', N'numeric', N'smallint', N'tinyint') and t.scale = 0) then 1 else 0 end,
  927.             variablelength = t.variable,
  928.             /* char count for string datatype, byte count for others */
  929.                 maxlen = case when s.dt_basetype in (N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar') then t.prec else t.length end,
  930.             defaultowner = dt_defowner,
  931.             ruleowner = dt_rulowner
  932.             from systypes t, #sphelptype s
  933.             where t.xusertype > 256 and (@typename is null or t.name = @typename)
  934.                 and dt_xusertype = t.xusertype
  935.             order by t.name
  936.     end
  937. go
  938. /* End sp_MShelptype */
  939.  
  940. /*******************************************************************************/
  941. print N''
  942. print N'Creating sp_MSdependencies'
  943. print N''
  944. go
  945.  
  946. create procedure sp_MSdependencies
  947. @objname nvarchar(517) = null, @objtype int = null, @flags int = 0x01fd, @objlist nvarchar(128) = null
  948. as
  949.     if (@objname = N'?')
  950.     begin
  951.         print N'sp_MSobject_dependencies name = NULL, type = NULL, flags = 0x01fd'
  952.         print N'  name:  name or null (all objects of type)'
  953.         print N'  type:  type number (see below) or null'
  954.         print N'      if both null, get all objects in database'
  955.         print N'  flags is a bitmask of the following values:'
  956.         print N'      0x10000  = return multiple parent/child rows per object'
  957.         print N'      0x20000  = descending return order'
  958.         print N'      0x40000  = return children instead of parents'
  959.         print N'      0x80000  = Include input object in output result set'
  960.         print N'      0x100000 = return only firstlevel (immediate) parents/children'
  961.         print N'      0x200000 = return only DRI dependencies'
  962.         print N'      power(2, object type number(s))  to return in results set:'
  963.         print N'          0 (1      - 0x0001)     - datatype'
  964.         print N'          1 (2      - 0x0002)     - system tables or MS-internal objects'
  965.         print N'          2 (4      - 0x0004)     - view'
  966.         print N'          3 (8      - 0x0008)     - user table'
  967.         print N'          4 (16        - 0x0010)     - procedure'
  968.         print N'          5 (32        - 0x0020)     - log'
  969.         print N'          6 (64     - 0x0040)     - default'
  970.         print N'          7 (128    - 0x0080)     - rule'
  971.         print N'          8 (256    - 0x0100)     - trigger'
  972.         print N'      shortcuts:'
  973.         print N'          29     (0x011c) - trig, view, user table, procedure'
  974.         print N'          448    (0x00c1) - rule, default, datatype'
  975.         print N'          509    (0x01fd) - all but systables/objects'
  976.         print N'          511    (0x01ff) - all'
  977.         return 0
  978.     end
  979.  
  980.     /* If this proc is called in a tight loop, it tends to fill up the log in a small tempdb too fast */
  981.     /* for the trunc. log on chkpt thread to keep up.  So help it out here.                           */
  982.    /* I can do this only if the current login has the proper permission to dump tempdb               */
  983.    /* In order to find out this information, I need to switch to tempdb                              */
  984.     declare @origdb nvarchar(128)
  985.    declare @tempdbName nvarchar(258)
  986.     select @origdb = db_name()
  987.    SELECT @tempdbName = REPLACE(@origdb, N']', N']]')
  988.    exec (N'if (has_dbaccess(''tempdb'') = 1) begin use tempdb if (permissions() & 0x80 <> 0) dump tran tempdb with no_log use [' + @tempdbName + N'] end')
  989.  
  990.     /* If they want SQLDMODep_DRIOnly, remove all but usertable objects from @flags */
  991.     if (@flags & 0x200000 <> 0)
  992.         select @flags = (@flags & ~convert(int, 0x01ff)) | power(2, 3)
  993.  
  994.     if (@objtype in (0, 5, 6, 7))
  995.     begin
  996.         /* Print only, do not raiserror as we may be calling this blindly and this is not a real error. */
  997.         print N'Rules, defaults, and datatypes do not have dependencies.'
  998.         return (0)
  999.     end
  1000.  
  1001.     /*
  1002.      * Create #t1 and #t2 as temp object holding areas.  Columns are:
  1003.      *     tid        - temp object id
  1004.      *     ttype     - temp object type
  1005.      *     pid        - parent or child object id
  1006.      *     ptype     - parent or child object type
  1007.      *     bDone     - NULL means dependencies not yet evaluated, else nonNULL.
  1008.      */
  1009.     declare @curid int, @curcat int, @rowsaffected int
  1010.     declare @allobjs int
  1011.     declare @delinputobj int
  1012.     select @allobjs = 0, @delinputobj = 0, @curid = NULL, @curcat = NULL
  1013.     create table #t1 (
  1014.         tid                int                NULL,
  1015.         ttype            smallint        NULL,
  1016.         tcat            smallint        NULL,
  1017.         pid                int                NULL,
  1018.         ptype            smallint        NULL,
  1019.         pcat            smallint        NULL,
  1020.         bDone            smallint        NULL
  1021.     )
  1022.     create table #t2 (
  1023.         tid                int                NULL,
  1024.         ttype            smallint        NULL,
  1025.         tcat            smallint        NULL,
  1026.         pid                int                NULL,
  1027.         ptype            smallint        NULL,
  1028.         pcat            smallint        NULL,
  1029.         bDone            smallint        NULL
  1030.     )
  1031.     create table #tempudt (
  1032.         dtype            int                NOT NULL
  1033.     )
  1034.  
  1035.     /* Worktables we'll use for optimization. */
  1036.     create table #t3 (
  1037.         tid                int                NOT NULL
  1038.     )
  1039.     create table #t4 (
  1040.         tid                int                NOT NULL
  1041.     )
  1042.     /* create clustered index #ci_t3 on #t3(tid) with allow_dup_row */
  1043.     /* create clustered index #ci_t4 on #t4(tid) with allow_dup_row */
  1044.     create clustered index #ci_t3 on #t3(tid)
  1045.     create clustered index #ci_t4 on #t4(tid)
  1046.     create table #temptrig(
  1047.         id                int                NOT NULL,
  1048.         deltrig            int                NOT NULL,
  1049.         sysstat            smallint        NOT NULL,
  1050.         category        int                NOT NULL
  1051.     )
  1052.     /* create clustered index #ci_temptrig on #temptrig (deltrig) with allow_dup_row */
  1053.     create clustered index #ci_temptrig on #temptrig (deltrig)
  1054.  
  1055.     /*
  1056.      * If both name and type are null, this means get every object in the
  1057.      * database matching the specification they passed in.  Otherwise,
  1058.      * find the passed object or all objects of the passed type.  Start off
  1059.      * loading parent info (pid, tid); these will be put into child as needed.
  1060.      * If Objlist is specified we simply load its contents into #t1.
  1061.      */
  1062.     if (@objlist is not null)
  1063.     begin
  1064.         declare @mscategory nvarchar(12)
  1065.         select @mscategory = ltrim(str(convert(int, 0x0002)))
  1066.  
  1067.         exec(N'insert #t1 (pid, ptype, pcat) select l.objid, l.objtype, o.category &' +  @mscategory +
  1068.                 N' from ' + @objlist + N' l, sysobjects o where o.id = l.objid ')
  1069.     end else begin
  1070.         if (@objname is null and @objtype is null)
  1071.         begin
  1072.             set nocount on
  1073.             select @allobjs = 1
  1074.             insert #t1 (pid, ptype, pcat) select o.id, o.sysstat & 0x0f, o.category & 0x0002 from sysobjects o
  1075.                 where ((power(2, o.sysstat & 0x0f) & 0x01ff) <> 0) and (OBJECTPROPERTY(o.id, N'IsDefaultCnst') <> 1 and OBJECTPROPERTY(o.id, N'IsRule') <> 1 )
  1076.         end else begin
  1077.             if (@objname is not null)
  1078.             begin
  1079.                 select @curid = id, @objtype = o.sysstat & 0x0f, @curcat = o.category & 0x0002 from sysobjects o where id = object_id(@objname)
  1080.                 if (@curid is null)
  1081.                 begin
  1082.                     RAISERROR (15001, -1, -1, @objname)
  1083.                     return 1
  1084.                 end
  1085.                 if (@flags & 0x80000 = 0)
  1086.                     select @delinputobj = @curid
  1087.             end
  1088.  
  1089.             set nocount on
  1090.             if (@curid is null)
  1091.                 insert #t1 (pid, ptype, pcat) select o.id, o.sysstat & 0x0f, o.category & 0x0002 from sysobjects o
  1092.                     where o.sysstat & 0x0f = @objtype
  1093.             else
  1094.                 insert #t1 (pid, ptype, pcat) values (@curid, @objtype, @curcat)
  1095.         end
  1096.     end
  1097.     /*
  1098.      * All initial objects are loaded as parents/children.  Now we loop, creating
  1099.      * rows of child/parent relationships.  Use #t2 as a temp area for the selects
  1100.      * to simulate recursion; when they find no rows, we're done with this step.
  1101.      *
  1102.      * Note that triggers are weird; they're part of a table definition but can
  1103.      * also reference other tables, so we need to evaluate them both ways.  SQL
  1104.      * Server stores the table for a trigger object as its deltrig; if a trigger
  1105.      * references another table, that relationship is stored in sysdepends.
  1106.      * This peculiarity of triggers requires separating the object-retrieval pass
  1107.      * from the creation-sequence pass (below).  Also, the fact that trigger tables
  1108.      * are stored in a non-indexed column (deltrig) requires us to use a worktable
  1109.      * if we're returning triggers, so we don't continually tablescan sysobjects.
  1110.      */
  1111.  
  1112.     if (@flags & power(2, 8) != 0)
  1113.         insert #temptrig select d.id, d.deltrig, d.sysstat, d.category from sysobjects d where OBJECTPROPERTY(d.id, N'IsTrigger') = 1
  1114.  
  1115.     while (select count(*) from #t1 where bDone is null) > 0
  1116.     begin
  1117.         /*
  1118.          * Remove Microsoft-internal or other system objects from #t1, unless
  1119.          * @flags specified including system tables.  We do this here so that
  1120.          * cascaded system dependencies are not included unless specifically
  1121.          * requested.  For other restrictions, we wait until below so that all
  1122.          * cascaded object types are fully evaluated.
  1123.          */
  1124.         if (@flags & power(2, 1) = 0)
  1125.             delete #t1 where ttype = 1 or tcat = 0x0002 or pcat = 0x0002
  1126.  
  1127.         if (@flags & 0x40000 != 0)
  1128.         begin
  1129.             if (@flags & 0x200000 = 0) begin
  1130.                 /* Table --> Triggers */
  1131.                 if (@flags & power(2, 8) != 0)
  1132.                     insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1133.                         select distinct t.pid, t.ptype, t.pcat, o.id, o.sysstat & 0x0f, o.category & 0x0002 from #t1 t, #temptrig o
  1134.                             where t.bDone is null and t.ptype = 3 and o.deltrig = t.pid
  1135.  
  1136.                 /* Object --> sysdepends children */
  1137.                 insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1138.                     select distinct t.pid, t.ptype, t.pcat, d.id, o.sysstat & 0x0f, o.category & 0x0002
  1139.                     from #t1 t, sysdepends d, sysobjects o
  1140.                     where t.bDone is null and d.depid = t.pid and d.id = o.id
  1141.             end
  1142.  
  1143.             /* Object --> sysreferences children (FK tables referencing this one) */
  1144.             insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1145.                 select distinct t.pid, t.ptype, t.pcat, r.fkeyid, o.sysstat & 0x0f, o.category & 0x0002
  1146.                 from #t1 t, sysreferences r, sysobjects o
  1147.                 where t.bDone is null and r.rkeyid = t.pid and r.fkeyid = o.id
  1148.         end else begin
  1149.             if (@flags & 0x200000 = 0) begin
  1150.                 /* Trigger --> Table */
  1151.                 if (@flags & power(2, 3) != 0)
  1152.                     insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1153.                         select distinct t.pid, t.ptype, t.pcat, o.deltrig, u.sysstat & 0x0f, u.category & 0x0002
  1154.                               from #t1 t, sysobjects o, sysobjects u
  1155.                             where t.bDone is null and t.ptype = 8 and o.id = t.pid and o.deltrig != 0 and u.id = o.deltrig
  1156.  
  1157.                 /* Object --> sysdepends parents */
  1158.                 insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1159.                     select distinct t.pid, t.ptype, t.pcat, d.depid, o.sysstat & 0x0f, o.category & 0x0002
  1160.                     from #t1 t, sysdepends d, sysobjects o
  1161.                     where t.bDone is null and d.id = t.pid and d.depid = o.id
  1162.             end
  1163.  
  1164.             /* Object --> sysreferences parents (PK/UQ tables referenced by one) */
  1165.             insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1166.                 select distinct t.pid, t.ptype, t.pcat, r.rkeyid, o.sysstat & 0x0f, o.category & 0x0002
  1167.                 from #t1 t, sysreferences r, sysobjects o
  1168.                 where t.bDone is null and r.fkeyid = t.pid and r.rkeyid = o.id
  1169.         end
  1170.  
  1171.         /*
  1172.          * We have this generation of parents in #t2, so clear the current
  1173.          * child generation's bDone flags.  Then insert from #t2; the current
  1174.          * parent generation becomes the next loop's child generation, with
  1175.          * bDone = null until next loop's dependencies are selected.
  1176.          */
  1177.         update #t1 set bDone = 1
  1178.         insert #t1 select * from #t2 where #t2.tid not in
  1179.             (select tid from #t1 where #t1.tid = #t2.tid and #t1.pid = #t2.pid)
  1180.         truncate table #t2
  1181.  
  1182.         /* If they only want one level, we're done.    */
  1183.         if (@flags & 0x100000 <> 0)
  1184.             update #t1 set bDone = 1
  1185.     end
  1186.  
  1187.     /*
  1188.      * The inner loop above did not put parents with no parents into the
  1189.      * child (tid) list.  Do that now, then remove all rows where tid is
  1190.      * NULL, because these were initial objects which now have a tid row.
  1191.      * Just in case, remove self-refs from #t1, and also remove rows from #t1
  1192.      * with NULL pid if a row exists for that tid where the pid is nonNULL.
  1193.      * Avoid nested self-joins by using worktables.
  1194.      */
  1195.     truncate table #t3
  1196.     insert #t3 select tid from #t1 where tid is not null
  1197.         and tid <> pid                -- make sure self-refs with no other refs go in child list
  1198.     /* update statistics #t3 #ci_t3 */
  1199.     insert #t1 (tid, ttype, tcat, bDone) select distinct pid, ptype, pcat, 0 from #t1 t
  1200.         where t.pid is not null and not exists (select * from #t3 where tid = t.pid)
  1201.     delete #t1 where tid = pid        -- now remove self-refs
  1202.  
  1203.     /*
  1204.      * Because triggers can go in both directions, we'll need to check for
  1205.      * circular dependencies on parent evaluation.  Since any tables referenced
  1206.      * by the trigger must exist before the trigger can be created, remove rows
  1207.      * where the trigger is the parent.
  1208.      */
  1209.     if (@flags & 0x40000 = 0)
  1210.         delete #t1 where ptype = 8
  1211.  
  1212.     truncate table #t3
  1213.     insert #t3 select tid from #t1 where tid is not null and pid is not null
  1214.     /* update statistics #t3 #ci_t3 */
  1215.     delete #t1 where #t1.tid is null or #t1.tid = #t1.pid
  1216.         or (#t1.pid is null and exists (select * from #t3 where tid = #t1.tid))
  1217.  
  1218.     /*
  1219.      * If we're to get all objects, get all UDDTs (which aren't in sysobjects)
  1220.      * and Rules/Defaults, assuming we're returning those types.
  1221.      */
  1222.     if (@allobjs <> 0)
  1223.     begin
  1224.         if (@flags & power(2, 0) != 0)
  1225.             insert #tempudt
  1226.                 select xusertype from systypes where xusertype > 256
  1227.         if (@flags & (power(2, 7) | power(2, 6)) != 0)
  1228.             insert #t2 (tid, ttype, tcat)
  1229.                 select id, sysstat & 0x0f, 0 from sysobjects
  1230.                 where (OBJECTPROPERTY(id, N'IsRule') = 1 or OBJECTPROPERTY(id, N'IsDefault') = 1)
  1231.                 and category & 0x0800 = 0
  1232.     end else begin
  1233.         /*
  1234.          * Not getting all objects.  Get any datatypes that
  1235.          * are referenced by objects in #t1.  We don't care about specific
  1236.          * datatype dependencies, we just want to know which ones are needed.
  1237.          */
  1238.         if (@flags & power(2, 0) != 0)
  1239.             insert #tempudt select distinct xusertype from syscolumns
  1240.                 where xusertype > 256 and id in (select tid from #t1)
  1241.  
  1242.         /*
  1243.          * Load rules and defaults needed by datatypes and other #t1 objects
  1244.          * into #t2.  Don't track specific object dependencies with these;
  1245.          * we just want to know which ones are needed.  For defaults only, eliminate
  1246.          * those which are constraints.
  1247.          */
  1248.         if (@flags & power(2, 7) != 0)
  1249.         begin
  1250.             insert #t2 (tid, ttype, tcat)
  1251.                 select distinct s.domain, 7, 0 from systypes s, #tempudt t
  1252.                     where s.domain != 0 and s.xusertype = t.dtype
  1253.                         and s.domain not in (select tid from #t1)
  1254.             insert #t2 (tid, ttype, tcat)
  1255.                 select distinct s.domain, 7, 0 from syscolumns s, #t1 t
  1256.                     where s.domain != 0 and s.id = t.tid
  1257.                         and s.domain not in (select tid from #t1)
  1258.         end
  1259.         if (@flags & power(2, 6) != 0)
  1260.         begin
  1261.             insert #t2 (tid, ttype, tcat)
  1262.                 select distinct s.tdefault, 6, 0 from systypes s, #tempudt t
  1263.                     where s.tdefault != 0 and s.xusertype = t.dtype
  1264.                         and s.tdefault not in (select tid from #t1)
  1265.                         and s.tdefault not in (select id from sysobjects where category & 0x0800 != 0)
  1266.             insert #t2 (tid, ttype, tcat)
  1267.                 select distinct s.cdefault, 6, 0 from syscolumns s, #t1 t
  1268.                     where s.cdefault != 0 and s.id = t.tid
  1269.                         and s.cdefault not in (select tid from #t1)
  1270.                         and s.cdefault not in (select id from sysobjects where category & 0x0800 != 0)
  1271.         end
  1272.     end        /* Not getting all objects */
  1273.  
  1274.     /*
  1275.      * Now that we've got all objects we want, eliminate those we don't
  1276.      * want to return.  If @inputobj and they don't want it returned,
  1277.      * remove it from the table.  Then eliminate object types they don't
  1278.      * want returned.  Make sure that in doing so we retain all parent
  1279.      * objects of the types we do want -- it is possible at this point
  1280.      * that a tid we want has no rows except those with pids we don't want.
  1281.      */
  1282.     if (@flags & 0x01ff != 0x01ff or @delinputobj != 0)
  1283.     begin
  1284.         delete #t1 where @flags & power(2, ttype) = 0 or tid = @delinputobj
  1285.  
  1286.         /*
  1287.          * Be sure that the insert does not duplicate rows that will survive the
  1288.          * following delete -- these are rows where the pid is not @delinputobj
  1289.          * and ptype is either null or a type we'll keep (if ptype is null then
  1290.          * pid hasn't been set so no need for more complex checking).
  1291.          */
  1292.         insert #t1 (tid, ttype, tcat) select distinct tid, ttype, tcat from #t1
  1293.             where (@flags & power(2, ptype) = 0 or pid = @delinputobj)
  1294.                 and tid not in (select tid from #t1 where ptype is null or
  1295.                     (pid != @delinputobj and @flags & power(2, ptype) != 0))
  1296.         delete #t1 where @flags & power(2, ptype) = 0 or pid = @delinputobj
  1297.     end
  1298.  
  1299.     /*
  1300.      * To determine creation order, find all objects which are not yet bDone
  1301.      * and have no parents or whose parents are all bDone, and set their bDone
  1302.      * to the next @curid.  This will leave bDone as the ascending order in
  1303.      * which objects must be created (topological sort).  Again, use worktables
  1304.      * to remove nested self-joins.
  1305.      */
  1306.     update #t1 set bDone = 0
  1307.     select @curid = 1, @rowsaffected = 1
  1308.     while (@rowsaffected <> 0)
  1309.     begin
  1310.         if (@flags & 0x40000 != 0) begin
  1311.             truncate table #t3
  1312.             insert #t3 select pid from #t1 where pid is not null and bDone = 0
  1313.             /* update statistics #t3 #ci_t3 */
  1314.             update #t1 set bDone = @curid where bDone = 0 and tid not in (select tid from #t3)
  1315.         end else begin
  1316.             truncate table #t3
  1317.             truncate table #t4
  1318.             insert #t3 select tid from #t1 where bDone = 0                /* Parents not yet done */
  1319.             /* update statistics #t3 #ci_t3 */
  1320.             insert #t4 select tid from #t1                                /* TIDs with (parents not yet done) */
  1321.                 where pid is not null and pid in (select tid from #t3)
  1322.             /* update statistics #t4 #ci_t4 */
  1323.             update #t1 set #t1.bDone = @curid where #t1.bDone = 0         /* TIDs who are not (TIDs with (parents not yet done)) */
  1324.                 and not exists (select * from #t4 where tid = #t1.tid)
  1325.         end
  1326.         select @rowsaffected = @@rowcount, @curid = @curid + 1
  1327.     end
  1328.  
  1329.     /* For SQL60 only, we need to check circular dependencies (DRI for tables is the only way to get them). */
  1330.     /* This will have occurred if we still have any rows in #t1 where bDone = 0, after the above loop. */
  1331.     /*
  1332.      * At this point, these are indirect (a->b->...->a), and can only be created by:
  1333.      *     create table a; create table b ref a; alter table a ref b
  1334.      * There is thus no way to create the tables in a single pass.  Further, the ALTER
  1335.      * TABLE B must be done AFTER data has been added (else the PK/FK will fail).
  1336.      * Therefore, the two-step model of
  1337.      *  - Create tables (and other objects)
  1338.      *  - Transfer data
  1339.      * does not work, so assume anyone doing this will do it in three passes (e.g. ScriptTransfer):
  1340.      *  - Create tables (and other objects) but no references (also defer some indexing, for perfomance)
  1341.      *  - Transfer data
  1342.      *  - Create references (and deferred indexing)
  1343.      * and just set bDone for everything remaining to @curid.
  1344.      */
  1345.     if exists (select * from #t1 where bDone = 0) begin
  1346.         --select "Circular Dependencies", object_name(tid) from #t1 where bDone = 0
  1347.         --RAISERROR (14300, -1, -1)
  1348.         --return 1
  1349.         update #t1 set bDone = @curid where bDone = 0
  1350.     end
  1351.  
  1352.     /*
  1353.      * Finally, return the objects.  Rules/Defaults must be created first so they're returned first,
  1354.      * followed by UDDTs. followed by all other (sysdepends/DRI) dependencies.  @curid is the bDone
  1355.      * value; we need to increment the #t1 value so our multi-result-set is in the proper sequence.
  1356.      * Of course, these never have parents, so don't return them if asking for children.
  1357.      */
  1358.     if (@flags & 0x40000 = 0) begin
  1359.         select @curid = 1
  1360.         if ((@flags & (power(2, 7) | power(2, 6)) != 0) and exists (select * from #t2)) begin
  1361.             update #t1 set bDone = bDone + 1
  1362.             select distinct oType = power(2, o.sysstat & 0x0f), oRuleDefName = o.name, oOwner = user_name(o.uid), oSequence = convert(smallint, @curid)
  1363.                 from sysobjects o, #t2 t
  1364.                 where o.id = t.tid
  1365.                 order by power(2, o.sysstat & 0x0f), o.name
  1366.             select @curid = @curid + 1
  1367.         end
  1368.         if ((@flags & power(2, 0) != 0) and exists (select * from #tempudt)) begin
  1369.             update #t1 set bDone = bDone + 1
  1370.             select distinct oType = power(2, 0), oUDDTName = c.name, oOwner = user_name(c.uid), oSequence = convert(smallint, @curid)
  1371.                 from systypes c, #tempudt t, sysobjects p
  1372.                 where c.xusertype = t.dtype
  1373.                 order by c.name
  1374.             select @curid = @curid + 1
  1375.         end
  1376.     end
  1377.  
  1378.     /*
  1379.      * Select dependency-style objects, returning parents if desired.
  1380.      * Normally sorting is in terms of who must be created first, i.e. ascending:  parent-->child-->grandchild.
  1381.      * Descending order (child-->parent-->grandparent) would be used for a graphical-dependencies evaluator showing
  1382.      * the parents.  Therefore we invert bDone if descending sort.  bDone is 1-based; min + max - bDone gives inversion.
  1383.      * Note:  Always return at least this empty set.
  1384.      */
  1385.     if (@flags & 0x20000 != 0) begin
  1386.         select @curid = max(bDone) + min(bDone) from #t1
  1387.         update #t1 set bDone = convert(smallint, @curid) - bDone
  1388.     end
  1389.     if (@flags & 0x10000 != 0)
  1390.         select distinct oType = power(2, o.sysstat & 0x0f), oObjName = o.name, oOwner = user_name(o.uid),
  1391. /*                RelType = power(2, p.sysstat & OBJTYPE_BITS), RelName = p.name, RelOwner = user_name(p.uid), */
  1392.                 RelType = case when (p.name is not null) then power(2, p.sysstat & 0x0f) else 0 end, RelName = p.name, RelOwner = user_name(p.uid),
  1393.                 oSequence = t.bDone
  1394.             from sysobjects o, sysobjects p, #t1 t
  1395.             where o.id = t.tid and p.id =* t.pid
  1396.             order by t.bDone, power(2, o.sysstat & 0x0f), o.name
  1397.     else
  1398.         select distinct oType = power(2, o.sysstat & 0x0f), oObjName = o.name, oOwner = user_name(o.uid),
  1399.                 oSequence = t.bDone
  1400.             from sysobjects o, #t1 t
  1401.             where o.id = t.tid
  1402.             order by t.bDone, power(2, o.sysstat & 0x0f), o.name
  1403.  
  1404. go
  1405. /* End sp_MSdependencies */
  1406.  
  1407. /************* DUMP THE TRANSACTION LOG **************************************/
  1408. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  1409. /* script periodically, you will run out of transaction log space.           */
  1410. print N''
  1411. print N'Dumping transaction log...'
  1412. print N''
  1413. go
  1414. dump tran master with no_log
  1415. go
  1416. /************* END DUMP THE TRANSACTION LOG **********************************/
  1417.  
  1418. /*******************************************************************************/
  1419. print N''
  1420. print N'Creating sp_MStablespace'
  1421. print N''
  1422. go
  1423.  
  1424. create procedure sp_MStablespace
  1425. @name nvarchar(517), @id int = null
  1426. as
  1427.     declare @rows int, @datasizeused int, @indexsizeused int, @pagesize int
  1428.     declare @dbname nvarchar(128)
  1429.     select @dbname = db_name()
  1430.  
  1431.     if (@id is null)
  1432.         select @id = id from sysobjects where id = object_id(@name) and (OBJECTPROPERTY(id, N'IsTable') = 1)
  1433.     if (@id is null)
  1434.     begin
  1435.         RAISERROR (15009, -1, -1, @name, @dbname)
  1436.         return 1
  1437.     end
  1438.  
  1439.     /* rows */
  1440.     SELECT @rows = rows
  1441.         FROM sysindexes
  1442.         WHERE indid < 2 and id = @id
  1443.  
  1444.     /* data */
  1445.     SELECT @datasizeused =
  1446.     (SELECT sum(dpages)
  1447.      FROM sysindexes
  1448.      WHERE indid < 2 and id = @id)
  1449.     +
  1450.     (SELECT isnull(sum(used), 0)
  1451.      FROM sysindexes
  1452.      WHERE indid = 255 and id = @id)
  1453.  
  1454.    /* Do not consider 2 < indid < 255 rows, those are nonclustered indices, and the space used by them are included by indid = 0(table) */
  1455.    /* or indid = 1(clustered index) already.  indid = 0(table) and = 1(clustered index) are mutual exclusive */
  1456.     /* index */
  1457.     SELECT @indexsizeused =
  1458.     (SELECT sum(used)
  1459.      FROM sysindexes
  1460.      WHERE indid in (0, 1, 255) and id = @id)
  1461.      - @datasizeused
  1462.  
  1463.     /* Pagesize on this server (sysindexes stores size info in pages) */
  1464.     select @pagesize = v.low / 1024 from master..spt_values v where v.number=1 and v.type=N'E'
  1465.  
  1466.     select Rows = @rows, DataSpaceUsed = @datasizeused * @pagesize, IndexSpaceUsed = @indexsizeused * @pagesize
  1467. go
  1468.  
  1469. /* End sp_MStablespace */
  1470.  
  1471. /*******************************************************************************/
  1472. print N''
  1473. print N'Creating sp_MSindexspace'
  1474. print N''
  1475. go
  1476.  
  1477. CREATE PROCEDURE sp_MSindexspace
  1478.     @tablename nvarchar(517), @index_name nvarchar(258) = NULL
  1479. AS
  1480. BEGIN
  1481.   DECLARE @table_id int
  1482.   DECLARE @index_id int
  1483.   DECLARE @msg nvarchar(2000)
  1484.   DECLARE @pagesize int
  1485.   select @pagesize = v.low / 1024 from master..spt_values v where v.number=1 and v.type=N'E'
  1486.  
  1487.   /* Make sure @tablename is local to the current database */
  1488.   /* Check if server is pre 7.0 */
  1489.   if (@@version NOT LIKE N'%7.%.%') begin
  1490.      IF (@tablename like N'%.%.%') AND (substring(@tablename, 1, charindex(N'.', @tablename) - 1) <> db_name())
  1491.      BEGIN
  1492.          RAISERROR (15078, -1, -1, N'')
  1493.          RETURN(1)
  1494.      END
  1495.   end
  1496.  
  1497.   /* Make sure that @tablename and @index_name exist, we are checking table instead of UserTable */
  1498.   SELECT @table_id = id
  1499.   FROM sysobjects
  1500.   WHERE (id = object_id(@tablename))
  1501.     AND (OBJECTPROPERTY(id, N'IsTable') = 1)
  1502.   IF (@table_id is NULL)
  1503.   BEGIN
  1504.     RAISERROR (15001, -1, -1, @tablename)
  1505.     RETURN(1)
  1506.   END
  1507.   IF (@index_name is not NULL)
  1508.   BEGIN
  1509.     SELECT @index_id = indid
  1510.     FROM sysindexes
  1511.     WHERE (name = @index_name)
  1512.       AND (id = object_id(@tablename))
  1513.     IF (@index_id is NULL)
  1514.     BEGIN
  1515.       SELECT @msg = @tablename + N'.' + @index_name
  1516.       RAISERROR (15001, -1, -1, @msg)
  1517.       RETURN(1)
  1518.     END
  1519.   END
  1520.   /* Ok, we're good to go */
  1521.   IF (user_id() = 1)
  1522.     CHECKPOINT
  1523.   IF (@index_name is NULL)
  1524.   BEGIN
  1525.     CREATE TABLE #IndexSizeTemp (
  1526.         IndexID            tinyint            NOT NULL,
  1527.         IndexName        nvarchar(128)        NOT NULL,
  1528.         IndexSize        int                NOT NULL,
  1529.         Comments        nvarchar(28)        NOT NULL
  1530.     )
  1531.     INSERT INTO #IndexSizeTemp
  1532.     SELECT indid, name, 0, N''
  1533.     FROM sysindexes
  1534.     WHERE (id = object_id(@tablename))
  1535.       AND ((indid > 0) AND (indid < 255))
  1536.     UPDATE #IndexSizeTemp
  1537.     SET IndexSize = used * @pagesize,
  1538.         Comments = N'(None)'
  1539.     FROM sysindexes si, #IndexSizeTemp ist
  1540.     WHERE (id = object_id(@tablename))
  1541.       AND (indid > 1) AND (indid < 255)
  1542.       AND (si.indid = ist.IndexID)
  1543.     UPDATE #IndexSizeTemp
  1544.     SET IndexSize = (used - dpages - isnull((SELECT sum(used)
  1545.                                              FROM sysindexes
  1546.                                              WHERE (indid > 1) AND (indid < 255)
  1547.                                                AND (id = object_id(@tablename))), 0)) * @pagesize,
  1548.         Comments = N'Size excludes actual data.'
  1549.     FROM sysindexes si, #IndexSizeTemp ist
  1550.     WHERE (id = object_id(@tablename))
  1551.       AND (indid = 1)
  1552.       AND (si.indid = ist.IndexID)
  1553.     SELECT N'Index ID' = IndexID, N'Index Name' = IndexName, N'Size (KB)' = IndexSize, Comments
  1554.     FROM #IndexSizeTemp
  1555.     ORDER BY IndexID
  1556.     DROP TABLE #IndexSizeTemp
  1557.   END
  1558.   ELSE
  1559.   BEGIN
  1560.     DECLARE @indid int
  1561.     SELECT @indid = indid
  1562.     FROM sysindexes
  1563.     WHERE (id = object_id(@tablename))
  1564.       AND (name = @index_name)
  1565.     /* The non-clustered index case */
  1566.     IF ((@indid > 1) AND (@indid < 255))
  1567.     BEGIN
  1568.       SELECT N'Size (KB)' = used * @pagesize
  1569.       FROM sysindexes
  1570.       WHERE (id = object_id(@tablename))
  1571.         AND (name = @index_name)
  1572.       RETURN(0)
  1573.     END
  1574.     /* The clustered index case */
  1575.     IF (@indid = 1)
  1576.     BEGIN
  1577.       SELECT N'Size (KB)' =
  1578.              (used - dpages - isnull((SELECT sum(used)
  1579.                                       FROM sysindexes
  1580.                                       WHERE (indid > 1) AND (indid < 255)
  1581.                                         AND (id = object_id(@tablename))), 0)) * @pagesize
  1582.       FROM sysindexes
  1583.       WHERE (id = object_id(@tablename))
  1584.         AND (name = @index_name)
  1585.     END
  1586.   END
  1587.   RETURN(0)
  1588. END
  1589. go
  1590. /* End sp_MSindexspace */
  1591.  
  1592. /*-----------------------------------------------------*/
  1593. /*-----------------------------------------------------*/
  1594. print N''
  1595. print N'Creating sp_MStablerefs'
  1596. print N''
  1597. go
  1598.  
  1599. create procedure sp_MStablerefs
  1600.     @tablename nvarchar(517),                    
  1601.     @type nvarchar(20) = N'actualtables',        
  1602.     @direction nvarchar(20) = N'primary',        
  1603.     @reftable nvarchar(517) = null,            
  1604.    @flags int = 0
  1605. as
  1606.    /* tablename: table whose references are being evaluated */
  1607.    /* type     : '[actual | all][tables | keys | keycols]'; all candidates, or only those actually referenced */
  1608.    /* direction: look for references from @tablename to 'primary' table(s), or to @tablename from 'foreign' table(s) */
  1609.    /* reftable : limit scope to this table, if non-null */
  1610.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  1611.    /*** sp_MStablerefs '%s', null, 'both'                             ***/
  1612.  
  1613.     /* @flags is for daVinci */
  1614.     if (@flags is null)
  1615.         select @flags = 0
  1616.  
  1617.     if (@tablename = N'?') begin
  1618.         PRINT N''
  1619.         PRINT N'sp_MStablerefs:'
  1620.         PRINT N'@tablename nvarchar(257),                    /* table whose references are being evaluated */'
  1621.         PRINT N'@type nvarchar(20) = [actualtables],        /* [[actual | all][tables | keys | keycols]]; all candidates, or only those actually referenced */'
  1622.         PRINT N'@direction nvarchar(20) = [primary],        /* look for references from @tablename to [primary] or to @tablename from [foreign], or [both] */'
  1623.         PRINT N'@reftable nvarchar(257) = null                /* limit scope to this table, if non-null */'
  1624.         return 0
  1625.     end
  1626.  
  1627.     if (lower(@direction) = N'both') begin
  1628.         select
  1629.          N'PK_Table' = PKT.name,
  1630.          N'FK_Table' = FKT.name,
  1631.          N'Constraint' = object_name(r.constid),
  1632.             c.status,
  1633.             cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  1634.             cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  1635.             cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  1636.             cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  1637.             cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  1638.             cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  1639.             cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  1640.             cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  1641.             cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  1642.             cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  1643.             cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  1644.             cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  1645.             cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  1646.             cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  1647.             cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  1648.             cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16)),
  1649.             cRefCol1 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey1)),
  1650.             cRefCol2 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey2)),    
  1651.             cRefCol3 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey3)),
  1652.             cRefCol4 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey4)),
  1653.             cRefCol5 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey5)),
  1654.             cRefCol6 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey6)),
  1655.             cRefCol7 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey7)),
  1656.             cRefCol8 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey8)),
  1657.             cRefCol9 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey9)),
  1658.             cRefCol10 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey10)),
  1659.             cRefCol11 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey11)),
  1660.             cRefCol12 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey12)),
  1661.             cRefCol13 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey13)),
  1662.             cRefCol14 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey14)),
  1663.             cRefCol15 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey15)),
  1664.             cRefCol16 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey16)),
  1665.             N'PK_Table_Owner' = user_name(PKT.uid),
  1666.             N'FK_Table_Owner' = user_name(FKT.uid)
  1667.       from sysreferences r, sysconstraints c, sysobjects PKT, sysobjects FKT
  1668.       where r.constid = c.constid and (@tablename is null or
  1669.          (r.rkeyid = object_id(@tablename) or r.fkeyid = object_id(@tablename)))
  1670.       and PKT.id = r.rkeyid and FKT.id = r.fkeyid
  1671.       return 0
  1672.     end /* @direction = 'both' */
  1673.  
  1674.     declare @id int, @refid int
  1675.     select @id = object_id(@tablename), @refid = object_id(@reftable)
  1676.     if (@tablename is not null and @id is null) begin
  1677.         RAISERROR (15001, -1, -1, @tablename)
  1678.         return 1
  1679.     end
  1680.     if (@reftable is not null and @refid is null) begin
  1681.         RAISERROR (15001, -1, -1, @reftable)
  1682.         return 1
  1683.     end
  1684.  
  1685.     create table #sprefs (
  1686.         id                    int                NOT NULL,     /* id of reftable */
  1687.         constid                int                NULL,         /* id of key */
  1688.         referenced            bit                NOT NULL    /* well, is it? */
  1689.     )
  1690.  
  1691.     declare @dotables bit, @doall bit, @doprimary bit, @docols bit
  1692.     select     @dotables = case when (@type like N'allt%' or @type like N'actualt%') then 1 else 0 end,
  1693.             @doall = case when (@type like N'all%') then 1 else 0 end,
  1694.             @doprimary = case when (@direction like N'p%') then 1 else 0 end,
  1695.             @docols = case when (@type like N'%keycol%') then 1 else 0 end
  1696.  
  1697.     /* If a specific @tablename specified, see if it has the kind of keys we want. */
  1698.     /* If asking for references from @tablename to 'primary', we must have an FKEY; */
  1699.     /* if asking for references to @tablename from 'foreign', we must have an active REFerence. */
  1700.     if (@id is not null) begin
  1701.         declare @wantkeytype int
  1702.         select @wantkeytype = case @doprimary when 1 then 0x4 else 0x8 end
  1703.         if not exists (select * from sysobjects where id = @id and category & @wantkeytype <> 0)
  1704.             goto ReturnSet
  1705.     end
  1706.  
  1707.     if (@dotables = 1) begin
  1708.         if (@doprimary = 1) begin
  1709.             /* Get all candidate tables (those with Primary/Unique keys in sysconstraints). */
  1710.             insert #sprefs
  1711.                 select distinct id, null, 0 from sysconstraints where status & 0x0f in (1, 2)
  1712.  
  1713.             /* Update the referenced bit if this table references it. */
  1714.             update #sprefs set referenced = 1
  1715.                 where id in (select rkeyid from sysreferences where fkeyid = @id)
  1716.         end else begin
  1717.             /* All user tables are foreign-key candidate tables. */
  1718.             insert #sprefs
  1719.                 select distinct id, null, 0 from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1
  1720.  
  1721.             /* Update the referenced bit if it references this table. */
  1722.             update #sprefs set referenced = 1
  1723.                 where id in (select fkeyid from sysreferences where rkeyid = @id)
  1724.         end    /* direction */
  1725.  
  1726.     end else begin    /* keys */
  1727.         if (@doprimary = 1) begin
  1728.             /* Get all candidate tables (those with Primary/Unique keys in sysconstraints) and the keys. */
  1729.             insert #sprefs
  1730.                 select distinct id, constid, 0 from sysconstraints where status & 0x0f in (1, 2)
  1731.  
  1732.             /* Follow r.rkeyindid back to sysindexes to get the name and then 'rconstid' to see if this table references it. */
  1733.          update #sprefs set referenced = 1 from #sprefs s, sysreferences r, sysindexes i
  1734.             where r.fkeyid = @id
  1735.             and i.id = r.rkeyid and i.indid = r.rkeyindid and i.status & 0x1800 <> 0
  1736.             and s.constid = object_id(N'[' + REPLACE(i.name, N']', N']]') + N']')
  1737.  
  1738.         end else begin
  1739.             /* First add tables with FOREIGN keys defined. */
  1740.             insert #sprefs
  1741.                 select distinct id, constid, 0 from sysconstraints where status & 0x0f in (3)
  1742.  
  1743.             /* All user tables are foreign-key candidate tables, so add any tables we haven't yet, if @doall. */
  1744.             /* (This would be used for 'push' key definition; defining FK's from the standpoint of the PK table). */
  1745.             insert #sprefs
  1746.                 select distinct id, null, 0 from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1
  1747.                     and @doall = 1 and id not in (select id from #sprefs)
  1748.  
  1749.             /* Update the referenced bit if it references this table. */
  1750.             update #sprefs set referenced = 1
  1751.                 where constid in (select constid from sysreferences where rkeyid = @id)
  1752.         end    /* direction */
  1753.     end    /* tables or keys */
  1754.     
  1755.     /* Exclude system and MS-internal objects, or tables/keys that aren't in the @reftable we want, if any specified. */
  1756.     delete #sprefs where id in (select id from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') <> 1 or category & 0x0002 <> 0)
  1757.             or (@refid is not null and id != @refid)
  1758.  
  1759.     /* Output */
  1760. ReturnSet:
  1761.     if (@docols = 0) begin
  1762.         if (@tablename is not null) begin
  1763.             select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1764.                candidate_key = case @dotables when 1 then N'N/A' else object_name(s.constid) end, s.referenced
  1765.                from #sprefs s, sysobjects o where o.id = s.id and (@doall = 1 or s.referenced = 1)
  1766.                order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  1767.       end else begin
  1768.             select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1769.                candidate_key = case @dotables when 1 then N'N/A' else object_name(s.constid) end
  1770.                from #sprefs s, sysobjects o where o.id = s.id
  1771.                order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  1772.       end
  1773.     end else begin    /* @docols = 1 */
  1774.         /* This is currently just implemented for 'nonNULLtablename', 'actualkeycols', 'foreign'. */
  1775.          select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1776.                candidate_key = object_name(s.constid),
  1777.                cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  1778.                cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  1779.                cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  1780.                cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  1781.                cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  1782.                cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  1783.                cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  1784.                cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  1785.                cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  1786.                cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  1787.                cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  1788.                cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  1789.                cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  1790.                cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  1791.                cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  1792.                cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16))
  1793.             from #sprefs s, sysobjects o, sysreferences r
  1794.             where o.id = s.id and r.constid = s.constid and s.referenced = 1
  1795.             order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  1796.     end
  1797. go
  1798. /* End sp_MStablerefs */
  1799.  
  1800.  
  1801. /*******************************************************************************/
  1802. print N''
  1803. print N'Creating sp_MStablekeys'
  1804. print N''
  1805. go
  1806.  
  1807. create procedure sp_MStablekeys
  1808. @tablename nvarchar(776) = null, @colname nvarchar(258) = null, @type int = null, @keyname nvarchar(517) = null, @flags int = null
  1809. as
  1810.     /* This proc returns the table's DRI keys.  @type is the type(s) of key(s) to return. */
  1811.     /* Make sure @type is only the key types (DRI_PRIMARYKEY, DRI_UNIQUE, DRI_REFERENCE). */
  1812.     if (@type is null)
  1813.         select @type = 0x000e
  1814.     else
  1815.         select @type = @type & 0x000e
  1816.  
  1817.     /* Flags usage:  For daVinci, to pass call thru to sp_MStablerefs. */
  1818.     if (@flags is null)
  1819.         select @flags = 0
  1820.  
  1821.     set nocount on
  1822.     create table #spkeys
  1823.     (
  1824.         cType                tinyint            NOT NULL,    /* key Type */
  1825.         cName                nvarchar(258)        NOT NULL,    /* key Name */
  1826.         cFlags                int                NULL,        /* e.g., 1 = clustered for PK/Unique */
  1827.         cColCount            int                NULL,        /* number of columns (or column pairs) in the key */
  1828.         cFillFactor            tinyint            NULL,        /* Fill factor of index creation */
  1829.         cRefTable            nvarchar(520)        NULL,        /* owner-qual Referenced table name for FKs */
  1830.         cRefKey                nvarchar(260)        NULL,        /* name of referenced key in referenced table */
  1831.             -- Note:  cConstID replaces the column list used in 6.0, for speed.
  1832.             -- The output set MUST replace this with either index_col(@tablename, cIndexID, 1-16) and NULL * 16
  1833.             -- (for PK/UQ) UNION col_name(r.fkeyid, r.fkey1-16) and col_name(r.rkeyid, r.rkey1-16), for SQLDMO,
  1834.             -- and these MUST BE nvarchar(132) for alignment in the SQLDMO cache structure!
  1835.         cConstID            int                NULL,        /* Reference constraint ID, if Foreign Key  */
  1836.         cIndexID            int                NULL,        /* ID of this key's index, if PK/UQ */
  1837.         cGroupName        sysname        NULL,        /* FileGroup name of this key, if PK/UQ */
  1838.         cDisabled        int                NULL,        /* 0 if enabled, 1 if disabled */
  1839.         cPrimaryFG        int                NULL,        /* 1 if primary FG, 0 otherwise */
  1840.     )
  1841.  
  1842.     declare @cType int, @cName nvarchar(258), @cFlags int, @cRefTable nvarchar(520), @fillfactor tinyint
  1843.     declare @objid int, @constid int, @indid int, @keycnt int, @q1 nvarchar(2000), @q2 nvarchar(2000), @objtype int, @groupname sysname
  1844.     declare @haskeytypes int, @wantkeytypes int
  1845.    declare @cDisabled int, @PrimaryFG int
  1846.  
  1847.     /* First see if @keyname was defined, and override @tablename and @type if so. */
  1848.     if (@keyname is not null)
  1849.     begin
  1850.          select @objid = id, @type = power(2, status & 0x0f) from sysconstraints where constid = object_id(@keyname)
  1851.          if (@objid is null)    begin
  1852.             RAISERROR (15001, -1, -1, @keyname)
  1853.             return 1
  1854.          end
  1855.          /* Now get the tablename for the index_col below */
  1856.          select @tablename = N'[' + REPLACE(user_name(uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(name, N']', N']]') + N']' from sysobjects where id = @objid
  1857.     end else begin
  1858.         /* Want all keys for this table (of @type type). */
  1859.         select @objid = id, @objtype = (case when OBJECTPROPERTY(id, N'IsTable') = 1 then 1 else 0 end), @haskeytypes = category & 0x0604
  1860.             from sysobjects where id = object_id(@tablename)
  1861.         if (@objid is null)    begin
  1862.             RAISERROR (15001, -1, -1, @tablename)
  1863.             return 1
  1864.         end
  1865.         if (@objtype <> 1)    begin
  1866.             RAISERROR (15218, -1, -1, @tablename)
  1867.             return 1
  1868.         end
  1869.         if @colname is not null and not exists (select * from syscolumns where id = @objid and name = @colname) begin
  1870.             RAISERROR (15253, -1, -1, @colname, @tablename)
  1871.             return 1
  1872.         end
  1873.  
  1874.         /* Skip cursor opening if we don't have any keys (of the type wanted); return a set anyway, for the cache. */
  1875.         if (@haskeytypes = 0)
  1876.             goto ReturnSet
  1877.  
  1878.         /* Map from the input bitmask to the category bitmask */
  1879.         select @wantkeytypes = 0
  1880.         if ((@type & power(2, 1)) <> 0)
  1881.             select @wantkeytypes = @wantkeytypes | 0x200
  1882.         if ((@type & power(2, 2)) <> 0)
  1883.             select @wantkeytypes = @wantkeytypes | 0x400
  1884.         if ((@type & power(2, 3)) <> 0)
  1885.             select @wantkeytypes = @wantkeytypes | 0x4
  1886.         if ((@haskeytypes & @wantkeytypes) = 0)
  1887.             goto ReturnSet
  1888.     end
  1889.  
  1890.     /* Preprocessor won't replace within quotes so have to use str(). */
  1891.     declare @sysgenname nvarchar(12), @pkstr nvarchar(12), @uqstr nvarchar(12), @fkstr nvarchar(12), @objtypebits nvarchar(12)
  1892.     select @sysgenname = ltrim(str(convert(int, 0x00020000)))
  1893.     select @pkstr = ltrim(str(convert(int, 1)))
  1894.     select @uqstr = ltrim(str(convert(int, 2)))
  1895.     select @fkstr = ltrim(str(convert(int, 3)))
  1896.     select @objtypebits = ltrim(str(convert(int, 0x0f)))
  1897.  
  1898.     /* Other ints we need strings for */
  1899.     declare @objidstr nvarchar(12), @typestr nvarchar(12)
  1900.     select @objidstr = ltrim(str(@objid))
  1901.     select @typestr = ltrim(str(@type))
  1902.  
  1903.     /* Qualifying key name. */
  1904.     declare @qualkeyname nvarchar(100)
  1905.     select @qualkeyname = null
  1906.     if (@keyname is not null) begin
  1907.       select @qualkeyname = N' and constid = object_id(''' + @keyname + N''')'
  1908.    end
  1909.  
  1910.     /*********************/
  1911.     /* Main cursor loop. */
  1912.     /*********************/
  1913. /*      exec(N'declare hC insensitive cursor for select constid, status & ' + @objtypebits + N', status & ' + @sysgenname +  */
  1914.     exec(N'declare hC cursor global for select constid, status & ' + @objtypebits + N', status & ' + @sysgenname +
  1915.             N' from sysconstraints where id = ' + @objidstr + N' and (' + @typestr + N' & power(2, status & 0x0f) != 0) ' + @qualkeyname)
  1916.     open hC
  1917.     fetch hC into @constid, @cType, @cFlags
  1918.     while (@@fetch_status >= 0) begin
  1919.         if (object_name(@constid) is null) begin
  1920.             raiserror 55555 N'Assert failed:  object_name(@constid) is null in sp_MStablekeys (pk/uq)'
  1921.             return 1
  1922.         end
  1923.  
  1924.         /* DRI_PRIMARYKEY, DRI_UNIQUE */
  1925.         if (@cType in (1, 2)) begin
  1926.             /* Get the index id enforcing this constraint. */
  1927.             select @indid = i.indid, @cName = o.name, @fillfactor = i.OrigFillFactor,
  1928.                     @cFlags = @cFlags | (case indid when 1 then 0x00000001 else 0 end),        /* test for clustered index */
  1929.                /* clustered index keys are part of non-clustered index key list, which cause incorrect sysindexes.keycnt */
  1930.                     @keycnt = case indid when 1 then keycnt else (select count(x.id) from sysindexkeys x where i.indid = x.indid and x.id = @objid) end,
  1931.                @groupname = f.groupname,
  1932.                @PrimaryFG = FILEGROUPPROPERTY( f.groupname, N'IsPrimaryFG' )
  1933.                 from sysindexes i, sysobjects o, sysfilegroups f
  1934.             /* Use '=' instead of 'LIKE' in comparision, so we can handle wide card character correctly */
  1935.                 where o.id = @constid and i.name = o.name and i.status & 0x1800 <> 0 and i.groupid = f.groupid
  1936.             if (@indid is null) begin
  1937.                 raiserror 77777 N'Assert failed:  @indid is null in sp_MStablekeys (pk/uq)'
  1938.                 return 1
  1939.             end
  1940.  
  1941.             /* Load our temp table. */
  1942.             insert #spkeys values (@cType, @cName, @cFlags, @keycnt, @fillfactor, null, null, null, @indid, @groupname, 0, @PrimaryFG)
  1943.         end
  1944.  
  1945.         /* DRI_REFERENCE */
  1946.         else if (@cType in (3)) begin
  1947.             /* Get the key column information from sysreferences. */
  1948.          select @keycnt = r.keycnt, @cName = object_name(r.constid), @cRefTable = N'[' + user_name(o.uid) + N']' + N'.' + N'[' + o.name + N']',
  1949.                @cDisabled = OBJECTPROPERTY( r.constid, N'CnstIsDisabled' )
  1950.             from sysreferences r, sysobjects o where r.constid = @constid and o.id = r.rkeyid
  1951.  
  1952.             /* Follow r.rkeyindid back to sysindexes to get the ref key name. */
  1953.             declare @cRefKey nvarchar(132)
  1954.             select @cRefKey = i.name, @cFlags = c.status from sysreferences r, sysindexes i, sysconstraints c
  1955.                 where c.constid = r.constid and r.constid = @constid
  1956.                 and i.id = r.rkeyid and i.indid = r.rkeyindid and i.status & 0x1800 <> 0
  1957.  
  1958.             /* Load our temp table. */
  1959.             insert #spkeys values (@cType, @cName, @cFlags, @keycnt, null, @cRefTable, @cRefKey, @constid, null, null, @cDisabled, 0)
  1960.         end        /* Key type */
  1961.  
  1962.         /* Get the next row. */
  1963.         fetch hC into @constid, @cType, @cFlags
  1964.     end            /* PRIMARY/UNIQUE */
  1965.     deallocate hC
  1966.  
  1967.     /* Now output the data */
  1968. ReturnSet:
  1969.     set nocount off
  1970.     select cType, cName, cFlags, cColCount, cFillFactor, cRefTable, cRefKey,
  1971.             cKeyCol1 = convert(nvarchar(132), index_col(@tablename, cIndexID, 1)),
  1972.             cKeyCol2 = convert(nvarchar(132), index_col(@tablename, cIndexID, 2)),    
  1973.             cKeyCol3 = convert(nvarchar(132), index_col(@tablename, cIndexID, 3)),
  1974.             cKeyCol4 = convert(nvarchar(132), index_col(@tablename, cIndexID, 4)),
  1975.             cKeyCol5 = convert(nvarchar(132), index_col(@tablename, cIndexID, 5)),
  1976.             cKeyCol6 = convert(nvarchar(132), index_col(@tablename, cIndexID, 6)),    
  1977.             cKeyCol7 = convert(nvarchar(132), index_col(@tablename, cIndexID, 7)),
  1978.             cKeyCol8 = convert(nvarchar(132), index_col(@tablename, cIndexID, 8)),
  1979.             cKeyCol9 = convert(nvarchar(132), index_col(@tablename, cIndexID, 9)),
  1980.             cKeyCol10 = convert(nvarchar(132), index_col(@tablename, cIndexID, 10)),
  1981.             cKeyCol11 = convert(nvarchar(132), index_col(@tablename, cIndexID, 11)),
  1982.             cKeyCol12 = convert(nvarchar(132), index_col(@tablename, cIndexID, 12)),
  1983.             cKeyCol13 = convert(nvarchar(132), index_col(@tablename, cIndexID, 13)),
  1984.             cKeyCol14 = convert(nvarchar(132), index_col(@tablename, cIndexID, 14)),    
  1985.             cKeyCol15 = convert(nvarchar(132), index_col(@tablename, cIndexID, 15)),
  1986.             cKeyCol16 = convert(nvarchar(132), index_col(@tablename, cIndexID, 16)),
  1987.             cRefCol1 = convert(nvarchar(132), null),
  1988.             cRefCol2 = convert(nvarchar(132), null),
  1989.             cRefCol3 = convert(nvarchar(132), null),
  1990.             cRefCol4 = convert(nvarchar(132), null),
  1991.             cRefCol5 = convert(nvarchar(132), null),
  1992.             cRefCol6 = convert(nvarchar(132), null),
  1993.             cRefCol7 = convert(nvarchar(132), null),
  1994.             cRefCol8 = convert(nvarchar(132), null),
  1995.             cRefCol9 = convert(nvarchar(132), null),
  1996.             cRefCol10 = convert(nvarchar(132), null),
  1997.             cRefCol11 = convert(nvarchar(132), null),
  1998.             cRefCol12 = convert(nvarchar(132), null),
  1999.             cRefCol13 = convert(nvarchar(132), null),
  2000.             cRefCol14 = convert(nvarchar(132), null),
  2001.             cRefCol15 = convert(nvarchar(132), null),
  2002.             cRefCol16 = convert(nvarchar(132), null),
  2003.             cIndexID,
  2004.             cGroupName,
  2005.          cDisabled,
  2006.           cPrimaryFG
  2007.         from #spkeys where cType in (1, 2)
  2008.             and (@colname is null or
  2009.                 index_col(@tablename, cIndexID, 1) = @colname or
  2010.                 index_col(@tablename, cIndexID, 2) = @colname or
  2011.                 index_col(@tablename, cIndexID, 3) = @colname or
  2012.                 index_col(@tablename, cIndexID, 4) = @colname or
  2013.                 index_col(@tablename, cIndexID, 5) = @colname or
  2014.                 index_col(@tablename, cIndexID, 6) = @colname or
  2015.                 index_col(@tablename, cIndexID, 7) = @colname or
  2016.                 index_col(@tablename, cIndexID, 8) = @colname or
  2017.                 index_col(@tablename, cIndexID, 9) = @colname or
  2018.                 index_col(@tablename, cIndexID, 10) = @colname or
  2019.                 index_col(@tablename, cIndexID, 11) = @colname or
  2020.                 index_col(@tablename, cIndexID, 12) = @colname or
  2021.                 index_col(@tablename, cIndexID, 13) = @colname or
  2022.                 index_col(@tablename, cIndexID, 14) = @colname or
  2023.                 index_col(@tablename, cIndexID, 15) = @colname or
  2024.                 index_col(@tablename, cIndexID, 16) = @colname
  2025.             )
  2026.         UNION
  2027.         select c.cType, c.cName, c.cFlags, c.cColCount, c.cFillFactor, c.cRefTable, c.cRefKey,
  2028.             cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  2029.             cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  2030.             cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  2031.             cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  2032.             cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  2033.             cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  2034.             cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  2035.             cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  2036.             cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  2037.             cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  2038.             cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  2039.             cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  2040.             cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  2041.             cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  2042.             cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  2043.             cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16)),
  2044.             cRefCol1 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey1)),
  2045.             cRefCol2 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey2)),    
  2046.             cRefCol3 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey3)),
  2047.             cRefCol4 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey4)),
  2048.             cRefCol5 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey5)),
  2049.             cRefCol6 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey6)),
  2050.             cRefCol7 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey7)),
  2051.             cRefCol8 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey8)),
  2052.             cRefCol9 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey9)),
  2053.             cRefCol10 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey10)),
  2054.             cRefCol11 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey11)),
  2055.             cRefCol12 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey12)),
  2056.             cRefCol13 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey13)),
  2057.             cRefCol14 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey14)),
  2058.             cRefCol15 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey15)),
  2059.             cRefCol16 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey16)),
  2060.             cIndexID,
  2061.             cGroupName,
  2062.          cDisabled,
  2063.           cPrimaryFG
  2064.         from #spkeys c, sysreferences r where c.cType = 3 and r.constid = c.cConstID
  2065.             and (@colname is null or
  2066.                 col_name(r.fkeyid, r.fkey1) = @colname or
  2067.                 col_name(r.fkeyid, r.fkey2) = @colname or
  2068.                 col_name(r.fkeyid, r.fkey3) = @colname or
  2069.                 col_name(r.fkeyid, r.fkey4) = @colname or
  2070.                 col_name(r.fkeyid, r.fkey5) = @colname or
  2071.                 col_name(r.fkeyid, r.fkey6) = @colname or
  2072.                 col_name(r.fkeyid, r.fkey7) = @colname or
  2073.                 col_name(r.fkeyid, r.fkey8) = @colname or
  2074.                 col_name(r.fkeyid, r.fkey9) = @colname or
  2075.                 col_name(r.fkeyid, r.fkey10) = @colname or
  2076.                 col_name(r.fkeyid, r.fkey11) = @colname or
  2077.                 col_name(r.fkeyid, r.fkey12) = @colname or
  2078.                 col_name(r.fkeyid, r.fkey13) = @colname or
  2079.                 col_name(r.fkeyid, r.fkey14) = @colname or
  2080.                 col_name(r.fkeyid, r.fkey15) = @colname or
  2081.                 col_name(r.fkeyid, r.fkey16) = @colname
  2082.             )
  2083.         order by cType, cName
  2084.  
  2085.     if (@flags & 1 <> 0)
  2086.         exec sp_MStablerefs @tablename, N'actualkeycols', N'foreign'
  2087.  
  2088. go
  2089. /* End sp_MStablekeys */
  2090.  
  2091. /*-----------------------------------------------------*/
  2092. /*-----------------------------------------------------*/
  2093. print N''
  2094. print N'Creating sp_MStablechecks'
  2095. print N''
  2096. go
  2097.  
  2098. create procedure sp_MStablechecks
  2099.     @tablename nvarchar(517), @flags int = null
  2100. as
  2101.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  2102.    /*** sp_MStablechecks '%s'                                        ***/
  2103.  
  2104.     declare @id int
  2105.     select @id = object_id(@tablename)
  2106.     if (@id is null) begin
  2107.         RAISERROR (15001, -1, -1, @tablename)
  2108.         return 1
  2109.     end
  2110.  
  2111.     /* @flags is for daVinci. */
  2112.     if (@flags is null)
  2113.         select @flags = 0
  2114.  
  2115.     /* We'll put out the check text if it's all in one row (most likely); otherwise leave it */
  2116.     /* blank for refetching in its entirety via sp_helptext, unless @flags wants it anyway. */
  2117.     select object_name(t.id),
  2118.         case when (@flags & 1 <> 0 or not exists (select * from syscomments where id = t.id and colid = 2))
  2119.                 then t.text else null end,
  2120.         c.status & (convert(int, 0x00200000) | convert(int, 0x00020000) | convert(int, 0x00004000)),
  2121.       OBJECTPROPERTY( t.id, N'CnstIsDisabled' )
  2122.     from syscomments t, sysconstraints c
  2123.     where t.id = c.constid and c.id = @id and c.status & 0x0f = 4
  2124.         and (@flags & 1 <> 0 or t.colid = 1)
  2125.     order by object_name(t.id), t.colid
  2126. go
  2127. /* End sp_MStablechecks */
  2128.  
  2129. /*-----------------------------------------------------*/
  2130. /*-----------------------------------------------------*/
  2131. print N''
  2132. print N'Creating sp_MSsettopology'
  2133. print N''
  2134. go
  2135.  
  2136. /* Need this because it will set sysservers columns. */
  2137. sp_configure N'allow updates', 1
  2138. go
  2139. reconfigure with override
  2140. go
  2141.  
  2142. create procedure sp_MSsettopology
  2143.     @server nvarchar(258), @X int, @Y int
  2144. as
  2145.     update master..sysservers set topologyx = @X, topologyy = @Y
  2146.         where srvname = @server
  2147.     if (@@rowcount = 0) begin
  2148.         RAISERROR (15015, -1, -1, @server)
  2149.         return 1
  2150.     end
  2151.     return 0
  2152. go
  2153. /* End sp_MSsettopology */
  2154.  
  2155. sp_configure N'allow updates', 0
  2156. go
  2157. reconfigure with override
  2158. go
  2159.  
  2160. /*-----------------------------------------------------*/
  2161. /*-----------------------------------------------------*/
  2162. print N''
  2163. print N'Creating sp_MSmatchkey'
  2164. print N''
  2165. go
  2166.  
  2167. create proc sp_MSmatchkey
  2168.     @tablename nvarchar(517),
  2169.     @col1 nvarchar(258),
  2170.     @col2 nvarchar(258) = null,
  2171.     @col3 nvarchar(258) = null,
  2172.     @col4 nvarchar(258) = null,
  2173.     @col5 nvarchar(258) = null,
  2174.     @col6 nvarchar(258) = null,
  2175.     @col7 nvarchar(258) = null,
  2176.     @col8 nvarchar(258) = null,
  2177.     @col9 nvarchar(258) = null,
  2178.     @col10 nvarchar(258) = null,
  2179.     @col11 nvarchar(258) = null,
  2180.     @col12 nvarchar(258) = null,
  2181.     @col13 nvarchar(258) = null,
  2182.     @col14 nvarchar(258) = null,
  2183.     @col15 nvarchar(258) = null,
  2184.     @col16 nvarchar(258) = null
  2185. as
  2186.     declare @id int, @ii int, @colnotfound nvarchar(258), @keycnt int
  2187.     select @id = object_id(@tablename)
  2188.     if (@id is null) begin
  2189.         RAISERROR (15001, -1, -1, @tablename)
  2190.         return 1
  2191.     end
  2192.     select @ii = 1
  2193.     create table #t1 (        /* Join into this... */
  2194.         i                    int                NOT NULL,
  2195.         name                nvarchar(258)        NULL
  2196.     )
  2197.     insert #t1 values (1, @col1)
  2198.     insert #t1 values (2, @col2)
  2199.     insert #t1 values (3, @col3)
  2200.     insert #t1 values (4, @col4)
  2201.     insert #t1 values (5, @col5)
  2202.     insert #t1 values (6, @col6)
  2203.     insert #t1 values (7, @col7)
  2204.     insert #t1 values (8, @col8)
  2205.     insert #t1 values (9, @col9)
  2206.     insert #t1 values (10, @col10)
  2207.     insert #t1 values (11, @col11)
  2208.     insert #t1 values (12, @col12)
  2209.     insert #t1 values (13, @col13)
  2210.     insert #t1 values (14, @col14)
  2211.     insert #t1 values (15, @col15)
  2212.     insert #t1 values (16, @col16)
  2213.     delete #t1 where name is null
  2214.  
  2215.     select @colnotfound = min(name) from #t1 where name not in (select name from syscolumns where id = @id)
  2216.     if (@colnotfound is not null) begin
  2217.         RAISERROR (15253, -1, -1, @colnotfound, @tablename)
  2218.         return 1
  2219.     end
  2220.     select @ii = 1, @keycnt = count(*) from #t1
  2221.  
  2222.     /* Load all indexes which have the matching number of columns into a temp table, then eliminate those which don't qualify. */
  2223.     /* Remember the RID in the nc index is counted as a key */
  2224.     create table #i1 (
  2225.         i                    int                NOT NULL
  2226.     )
  2227.     insert #i1 select indid from sysindexes where status & 0x1800 <> 0
  2228.         and id = @id and keycnt - (case indid when 1 then 0 else 1 end) = @keycnt
  2229.     while (@ii <= @keycnt) begin
  2230.         delete #i1 from #i1 i, #t1 t where t.i = @ii and index_col(@tablename, i.i, t.i) <> t.name
  2231.         select @ii = @ii + 1
  2232.     end
  2233.  
  2234.     /* The qualifying key will be the lowest indid (or the ONLY indid, if we disallow duplicate indexes), if any remain. */
  2235.     select name from sysindexes where id = @id and indid = (select min(i) from #i1)
  2236. go
  2237. /* End sp_MSmatchkey */
  2238.  
  2239. /*-----------------------------------------------------*/
  2240. /*-----------------------------------------------------*/
  2241. print N''
  2242. print N'Creating sp_MSforeach_worker'
  2243. print N''
  2244. go
  2245.  
  2246. /*
  2247.  * This is the worker proc for all of the "for each" type procs.  Its function is to read the
  2248.  * next replacement name from the cursor (which returns only a single name), plug it into the
  2249.  * replacement locations for the commands, and execute them.  It assumes the cursor "hCForEach"
  2250.  * has already been opened by its caller.
  2251.  */
  2252. create proc sp_MSforeach_worker
  2253.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null, @command3 nvarchar(2000) = null
  2254. as
  2255.     set nocount on
  2256.     declare @name nvarchar(517), @namelen int, @q1 nvarchar(2000), @q2 nvarchar(2000)
  2257.    declare @q3 nvarchar(2000), @q4 nvarchar(2000), @q5 nvarchar(2000)
  2258.     declare @q6 nvarchar(2000), @q7 nvarchar(2000), @q8 nvarchar(2000), @q9 nvarchar(2000), @q10 nvarchar(2000)
  2259.     declare @cmd nvarchar(2000), @replacecharindex int, @useq tinyint, @usecmd tinyint, @nextcmd nvarchar(2000)
  2260.    declare @namesave nvarchar(517), @nametmp nvarchar(517), @nametmp2 nvarchar(258)
  2261.  
  2262.     create table #qtemp (    /* Temp command storage */
  2263.         qnum                int                NOT NULL,
  2264.         qchar                nvarchar(2000)    NULL
  2265.     )
  2266.     open hCForEach
  2267.     fetch hCForEach into @name
  2268.  
  2269.     /* Loop for each database */
  2270.     while (@@fetch_status >= 0) begin
  2271.         /* Initialize. */
  2272.  
  2273.       /* save the original dbname */
  2274.       select @namesave = @name
  2275.         select @useq = 1, @usecmd = 1, @cmd = @command1, @namelen = datalength(@name)
  2276.         while (@cmd is not null) begin        /* Generate @q* for exec() */
  2277.             /*
  2278.              * Parse each @commandX into a single executable batch.
  2279.              * Because the expanded form of a @commandX may be > OSQL_MAXCOLLEN_SET, we'll need to allow overflow.
  2280.              * We also may append @commandX's (signified by '++' as first letters of next @command).
  2281.              */
  2282.             select @replacecharindex = charindex(@replacechar, @cmd)
  2283.             while (@replacecharindex <> 0) begin
  2284.  
  2285.             /* 7.0, if name contains ' character, and the name has been single quoted in command, double all of them in dbname */
  2286.             /* if the name has not been single quoted in command, do not doulbe them */
  2287.             /* if name contains ] character, and the name has been [] quoted in command, double all of ] in dbname */
  2288.             select @name = @namesave
  2289.             select @namelen = datalength(@name)
  2290.             declare @tempindex int
  2291.             if (substring(@cmd, @replacecharindex - 1, 1) = N'''') begin
  2292.                /* if ? is inside of '', we need to double all the ' in name */
  2293.                select @name = REPLACE(@name, N'''', N'''''')
  2294.             end else if (substring(@cmd, @replacecharindex - 1, 1) = N'[') begin
  2295.                /* if ? is inside of [], we need to double all the ] in name */
  2296.                select @name = REPLACE(@name, N']', N']]')
  2297.             end else if ((@name LIKE N'%].%]') and (substring(@name, 1, 1) = N'[')) begin
  2298.                /* ? is NOT inside of [] nor '', and the name is in [owner].[name] format, handle it */
  2299.                /* !!! work around, when using LIKE to find string pattern, can't use '[', since LIKE operator is treating '[' as a wide char */
  2300.                select @tempindex = charindex(N'].[', @name)
  2301.                select @nametmp  = substring(@name, 2, @tempindex-2 )
  2302.                select @nametmp2 = substring(@name, @tempindex+3, len(@name)-@tempindex-3 )
  2303.                select @nametmp  = REPLACE(@nametmp, N']', N']]')
  2304.                select @nametmp2 = REPLACE(@nametmp2, N']', N']]')
  2305.                select @name = N'[' + @nametmp + N'].[' + @nametmp2 + ']'
  2306.             end else if ((@name LIKE N'%]') and (substring(@name, 1, 1) = N'[')) begin
  2307.                /* ? is NOT inside of [] nor '', and the name is in [name] format, handle it */
  2308.                /* j.i.c., since we should not fall into this case */
  2309.                /* !!! work around, when using LIKE to find string pattern, can't use '[', since LIKE operator is treating '[' as a wide char */
  2310.                select @nametmp = substring(@name, 2, len(@name)-2 )
  2311.                select @nametmp = REPLACE(@nametmp, N']', N']]')
  2312.                select @name = N'[' + @nametmp + N']'
  2313.             end
  2314.             /* Get the new length */
  2315.             select @namelen = datalength(@name)
  2316.  
  2317.             /* start normal process */
  2318.                 if (datalength(@cmd) + @namelen - 1 > 2000) begin
  2319.                     /* Overflow; put preceding stuff into the temp table */
  2320.                     if (@useq > 9) begin
  2321.                         raiserror 55555 N'sp_MSforeach_worker assert failed:  command too long'
  2322.                         close hCForEach
  2323.                         deallocate hCForEach
  2324.                         return 1
  2325.                     end
  2326.                     if (@replacecharindex < @namelen) begin
  2327.                         /* If this happened close to beginning, make sure expansion has enough room. */
  2328.                         /* In this case no trailing space can occur as the row ends with @name. */
  2329.                         select @nextcmd = substring(@cmd, 1, @replacecharindex)
  2330.                         select @cmd = substring(@cmd, @replacecharindex + 1, 2000)
  2331.                         select @nextcmd = stuff(@nextcmd, @replacecharindex, 1, @name)
  2332.                         select @replacecharindex = charindex(@replacechar, @cmd)
  2333.                         insert #qtemp values (@useq, @nextcmd)
  2334.                         select @useq = @useq + 1
  2335.                         continue
  2336.                     end
  2337.                     /* Move the string down and stuff() in-place. */
  2338.                     /* Because varchar columns trim trailing spaces, we may need to prepend one to the following string. */
  2339.                     /* In this case, the char to be replaced is moved over by one. */
  2340.                     insert #qtemp values (@useq, substring(@cmd, 1, @replacecharindex - 1))
  2341.                     if (substring(@cmd, @replacecharindex - 1, 1) = N' ') begin
  2342.                         select @cmd = N' ' + substring(@cmd, @replacecharindex, 2000)
  2343.                         select @replacecharindex = 2
  2344.                     end else begin
  2345.                         select @cmd = substring(@cmd, @replacecharindex, 2000)
  2346.                         select @replacecharindex = 1
  2347.                     end
  2348.                     select @useq = @useq + 1
  2349.                 end
  2350.                 select @cmd = stuff(@cmd, @replacecharindex, 1, @name)
  2351.                 select @replacecharindex = charindex(@replacechar, @cmd)
  2352.             end
  2353.  
  2354.             /* Done replacing for current @cmd.  Get the next one and see if it's to be appended. */
  2355.             select @usecmd = @usecmd + 1
  2356.             select @nextcmd = case (@usecmd) when 2 then @command2 when 3 then @command3 else null end
  2357.             if (@nextcmd is not null and substring(@nextcmd, 1, 2) = N'++') begin
  2358.                 insert #qtemp values (@useq, @cmd)
  2359.                 select @cmd = substring(@nextcmd, 3, 2000), @useq = @useq + 1
  2360.                 continue
  2361.             end
  2362.  
  2363.             /* Now exec() the generated @q*, and see if we had more commands to exec().  Continue even if errors. */
  2364.             /* Null them first as the no-result-set case won't. */
  2365.             select @q1 = null, @q2 = null, @q3 = null, @q4 = null, @q5 = null, @q6 = null, @q7 = null, @q8 = null, @q9 = null, @q10 = null
  2366.             select @q1 = qchar from #qtemp where qnum = 1
  2367.             select @q2 = qchar from #qtemp where qnum = 2
  2368.             select @q3 = qchar from #qtemp where qnum = 3
  2369.             select @q4 = qchar from #qtemp where qnum = 4
  2370.             select @q5 = qchar from #qtemp where qnum = 5
  2371.             select @q6 = qchar from #qtemp where qnum = 6
  2372.             select @q7 = qchar from #qtemp where qnum = 7
  2373.             select @q8 = qchar from #qtemp where qnum = 8
  2374.             select @q9 = qchar from #qtemp where qnum = 9
  2375.             select @q10 = qchar from #qtemp where qnum = 10
  2376.             truncate table #qtemp
  2377.             exec (@q1 + @q2 + @q3 + @q4 + @q5 + @q6 + @q7 + @q8 + @q9 + @q10 + @cmd)
  2378.             select @cmd = @nextcmd, @useq = 1
  2379.         end /* while @cmd is not null, generating @q* for exec() */
  2380.  
  2381.         /* All commands done for this name.  Go to next one. */
  2382.         fetch hCForEach into @name
  2383.     end /* while FETCH_SUCCESS */
  2384.     close hCForEach
  2385.     deallocate hCForEach
  2386.     return 0
  2387. go
  2388.  
  2389. /* End sp_MSforeach_worker */
  2390.  
  2391. /*-----------------------------------------------------*/
  2392. /*-----------------------------------------------------*/
  2393. print N''
  2394. print N'Creating sp_MSforeachdb'
  2395. print N''
  2396. go
  2397.  
  2398. /*
  2399.  * The following table definition will be created by SQLDMO at start of each connection.
  2400.  * We don't create it here temporarily because we need it in Exec() or upgrade won't work.
  2401.  */
  2402.  
  2403. create proc sp_MSforeachdb
  2404.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null, @command3 nvarchar(2000) = null,
  2405.     @precommand nvarchar(2000) = null, @postcommand nvarchar(2000) = null
  2406. as
  2407.     /* This proc returns one or more rows for each accessible db, with each db defaulting to its own result set */
  2408.     /* @precommand and @postcommand may be used to force a single result set via a temp table. */
  2409.  
  2410.     /* Preprocessor won't replace within quotes so have to use str(). */
  2411.     declare @inaccessible nvarchar(12), @invalidlogin nvarchar(12), @dbinaccessible nvarchar(12)
  2412.     select @inaccessible = ltrim(str(convert(int, 0x03e0), 11))
  2413.     select @invalidlogin = ltrim(str(convert(int, 0x40000000), 11))
  2414.     select @dbinaccessible = N'0x80000000'        /* SQLDMODbUserProf_InaccessibleDb; the negative number doesn't work in convert() */
  2415.  
  2416.     if (@precommand is not null)
  2417.         exec(@precommand)
  2418.  
  2419.     declare @origdb nvarchar(128)
  2420.     select @origdb = db_name()
  2421.  
  2422.     /* If it's a single user db and there's an entry for it in sysprocesses who isn't us, we can't use it. */
  2423.    /* Create the select */
  2424.     exec(N'declare hCForEach cursor global for select name from master..sysdatabases d ' +
  2425.             N' where (d.status & ' + @inaccessible + N' = 0)' +
  2426.             N' and ((DATABASEPROPERTY(d.name, ''issingleuser'') = 0 and (has_dbaccess(d.name) = 1)) or ' +
  2427.             N' ( DATABASEPROPERTY(d.name, ''issingleuser'') = 1 and not exists ' +
  2428.             N' (select * from master..sysprocesses p where dbid = d.dbid and p.spid <> @@spid)))' )
  2429.  
  2430.     declare @retval int
  2431.     select @retval = @@error
  2432.     if (@retval = 0)
  2433.         exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3
  2434.  
  2435.     if (@retval = 0 and @postcommand is not null)
  2436.         exec(@postcommand)
  2437.  
  2438.    declare @tempdb nvarchar(258)
  2439.    SELECT @tempdb = REPLACE(@origdb, N']', N']]')
  2440.    exec (N'use ' + N'[' + @tempdb + N']')
  2441.  
  2442.     return @retval
  2443. go
  2444. /* End sp_MSforeachdb */
  2445.  
  2446. /*-----------------------------------------------------*/
  2447. /*-----------------------------------------------------*/
  2448. print N''
  2449. print N'Creating sp_MSforeachtable'
  2450. print N''
  2451. go
  2452.  
  2453. create proc sp_MSforeachtable
  2454.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null,
  2455.    @command3 nvarchar(2000) = null, @whereand nvarchar(2000) = null,
  2456.     @precommand nvarchar(2000) = null, @postcommand nvarchar(2000) = null
  2457. as
  2458.     /* This proc returns one or more rows for each table (optionally, matching @where), with each table defaulting to its own result set */
  2459.     /* @precommand and @postcommand may be used to force a single result set via a temp table. */
  2460.  
  2461.     /* Preprocessor won't replace within quotes so have to use str(). */
  2462.     declare @mscat nvarchar(12)
  2463.     select @mscat = ltrim(str(convert(int, 0x0002)))
  2464.  
  2465.     if (@precommand is not null)
  2466.         exec(@precommand)
  2467.  
  2468.     /* Create the select */
  2469.    exec(N'declare hCForEach cursor global for select ''['' + REPLACE(user_name(uid), N'']'', N'']]'') + '']'' + ''.'' + ''['' + REPLACE(object_name(id), N'']'', N'']]'') + '']'' from sysobjects o '
  2470.          + N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + @mscat + N' = 0 '
  2471.          + @whereand)
  2472.     declare @retval int
  2473.     select @retval = @@error
  2474.     if (@retval = 0)
  2475.         exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3
  2476.  
  2477.     if (@retval = 0 and @postcommand is not null)
  2478.         exec(@postcommand)
  2479.  
  2480.     return @retval
  2481. go
  2482. /* End sp_MSforeachtable */
  2483.  
  2484. /*******************************************************************************/
  2485.  
  2486. print N''
  2487. print N'Creating sp_MSloginmappings'
  2488. print N''
  2489. go
  2490.  
  2491.  
  2492.  
  2493. create proc sp_MSloginmappings
  2494.     @loginname nvarchar(258) = null, @flags int = 0
  2495. as
  2496.     /*
  2497.      * @flags bits:
  2498.      *        0x01    - current db only
  2499.      */
  2500.     /*
  2501.      * Added @dbname so dbo can see everyone in current database.
  2502.      * Use hacky 4.21 syntax so it will run there, instead of a case..when.
  2503.      */
  2504.     declare @checkmultilogin int
  2505.     select @checkmultilogin = 1
  2506.     if ((@flags & 0x01 <> 0) and user_id() = 1)
  2507.         select @checkmultilogin = 0
  2508.  
  2509.     declare @logincount int
  2510.     select @logincount = 0
  2511.     if (@loginname is not null)
  2512.         select @logincount = count(*) from syslogins where loginname = @loginname
  2513.  
  2514.     /* Gotta be sa or dbo to see other than just current login. */
  2515.     declare @numlogins int, @whereloginname nvarchar(258), @name nvarchar(258), @retval int
  2516.     if (@loginname is null)
  2517.         select @numlogins = 2
  2518.     else
  2519.         select @numlogins = count(*) from syslogins where loginname = @loginname
  2520.  
  2521.     if (@numlogins = 0) begin
  2522.         RAISERROR (15007, -1, -1, @loginname)        /* Login not found */
  2523.         return 1
  2524.     end
  2525.     if (@checkmultilogin <> 0) begin
  2526.       /* We do not want to allow everybody to execute this SP */
  2527.         if (is_member(N'db_ddladmin') <> 1 and is_member(N'db_owner') <> 1 and is_member(N'db_accessadmin') <> 1 and is_member(N'db_securityadmin') <> 1 and (@numlogins > 1 or suser_sid() <> suser_sid(@loginname))) begin
  2528.             RAISERROR (14301, -1, -1, N'')                /* Only sa can see other than the current login */
  2529.             return 1
  2530.         end
  2531.     end
  2532.     if (@loginname is not null)
  2533.         select @whereloginname = N' and loginname = ''' + @loginname + N''''
  2534.    else
  2535.       select @whereloginname = N' '
  2536.  
  2537.     /*
  2538.      * This proc returns a result set with one or more rows for each database for which a login is a user or aliased to one.
  2539.      * If loginname is specified, the results are limited to that login.  First load a temp table with all logins that are
  2540.      * in a db, then add those which aren't mapped to any db.
  2541.      */
  2542.     create table #loginmappings(
  2543.         LoginName            nvarchar(128)        NULL,
  2544.         DBName                nvarchar(128)        NULL,
  2545.         UserName            nvarchar(128)        NULL,
  2546.         AliasName            nvarchar(128)        NULL
  2547.     )
  2548.     if (@flags & 0x01 <> 0) begin
  2549.         INSERT #loginmappings select l.loginname, db_name(), u.name, null from master..syslogins l, sysusers u where l.sid = u.sid and l.loginname is not NULL
  2550.         /*
  2551.          * We only allow multi-db on a 6.x server because dynamic exec() didn't exist before then,
  2552.          * hence there is no way to loop thru every database.  This is caught in SQLDMO so no
  2553.          * need for error message here; we'll just return no result sets.
  2554.          */
  2555.     end else begin
  2556.         exec @retval = sp_MSforeachdb
  2557.             N'use [?] INSERT #loginmappings select l.loginname, db_name(), u.name, null from master..syslogins l, sysusers u where l.sid = u.sid and l.loginname is not NULL'
  2558.         if (@retval <> 0)
  2559.             return 1
  2560.         insert #loginmappings select l.loginname, null, null, null from master..syslogins l where l.loginname not in (select LoginName from #loginmappings) and l.loginname is not NULL
  2561.     end
  2562.  
  2563.     /*
  2564.      * Now bring them out by loginname, each in its own result set.
  2565.      * If this is for all logins, we'll return all logins; if for curdb,
  2566.      * only those in #loginmappings (i.e. only those mapped in curdb).
  2567.      */
  2568.     exec(N'declare hCForEachLogin cursor global for select loginname from master..syslogins where loginname is not NULL ' + @whereloginname + N' order by loginname')
  2569.     if (@@error = 0)
  2570.         open hCForEachLogin
  2571.     if (@@error <> 0)
  2572.         return @@error
  2573.     fetch hCForEachLogin into @name
  2574.     while (@@fetch_status >= 0) begin
  2575.       /* Use '=' instead of 'LIKE' in comparision, so we can handle wide card character correctly */
  2576.         if ((@flags & 0x01 = 0) or exists (select * from #loginmappings where LoginName = @name))
  2577.             select * from #loginmappings where LoginName = @name
  2578.         fetch hCForEachLogin into @name
  2579.     end /* FETCH_SUCCESS */
  2580.     close hCForEachLogin
  2581.     deallocate hCForEachLogin
  2582.     return @@error
  2583. go
  2584. /* End sp_MSloginmappings */
  2585.  
  2586. /*******************************************************************************/
  2587. print N''
  2588. print N'Creating sp_MSuniquename'
  2589. print N''
  2590. go
  2591.  
  2592. create procedure sp_MSuniquename
  2593.     @seed nvarchar(128), @start int = null
  2594. as
  2595.     /* Return a unique name for sysobjects, based on a passed-in seed. */
  2596.     set nocount on
  2597.     declare @i int, @append nvarchar(10), @seedlen int, @temp nvarchar(128), @recalcseedlen int, @seedcharlen int
  2598.     select @i = 1, @seedlen = datalength(@seed), @recalcseedlen = 1, @seedcharlen = 0
  2599.     if (@start is not null and @start >= 0)
  2600.         select @i = @start
  2601.     while 1 < 2
  2602.     begin
  2603.         /* This is probably overkill, but start at max length of seed name, leaving room under OSQL_DBLSYSNAME_SET for @append. */
  2604.         /* We'll work our way back along the string if more room needed (pathological user). */
  2605.         select @append = ltrim(str(@i)) + N'__' + ltrim(str(@@spid))
  2606.         if (@recalcseedlen = @i or @seedcharlen = 0)
  2607.         begin
  2608.             while @recalcseedlen <= @i
  2609.                 select @recalcseedlen = @recalcseedlen * 10
  2610.             select @seedcharlen = @seedlen
  2611.             if ((@seedlen + datalength(@append)) > 128) begin
  2612.                 select @seedlen = 128 - datalength(@append)
  2613.  
  2614.                 /* Get the charlen of this datalength for the substring() call. */
  2615.                 select @seedcharlen = @seedlen
  2616.                /* exec sp_GetMBCSCharLen @seed, @seedlen, @seedcharlen out */
  2617.             end        /* Recalc seedlen */
  2618.         end        /* Check seedlen */
  2619.  
  2620.         select @temp = substring(@seed, 1, @seedcharlen) + @append
  2621.  
  2622.         /* If I don't set a limit somewhere, it's gonna look hung -- I'd rather get a nonunique error. */
  2623.         if object_id(@temp) is null or @i > 999999        /* if increased, watch out for overflow of @recalcseedlen */
  2624.         begin
  2625.             set nocount off
  2626.             select Name = @temp, Next = @i + 1
  2627.             return 0
  2628.         end
  2629.         select @i = @i + 1
  2630.     end
  2631. go
  2632. /* End sp_MSuniquename */
  2633.  
  2634. /*******************************************************************************/
  2635. print N''
  2636. print N'Creating sp_MSkilldb'
  2637. print N''
  2638. go
  2639.  
  2640. sp_configure updat, 1
  2641. go
  2642. reconfigure with override
  2643. go
  2644.  
  2645. create proc sp_MSkilldb
  2646.     @dbname nvarchar(258)
  2647. as
  2648.     if (@@trancount > 0) begin
  2649.         RAISERROR (15002, -1, -1, N'sp_MSkilldb')
  2650.         return 1
  2651.     end
  2652.  
  2653.     if (is_member(N'db_owner') <> 1 and is_member(N'db_ddladmin') <> 1) begin
  2654.         RAISERROR (15003, -1, -1, N'')
  2655.         return 1
  2656.     end
  2657.  
  2658.     /* Set this db to suspect, then let dbcc dbrepair kill it for us. */
  2659.     update master..sysdatabases set status = status | 0x0100
  2660.         where name = @dbname
  2661.     if (@@rowcount = 0) begin
  2662.         declare @len int
  2663.         select @len = datalength(@dbname)
  2664.         RAISERROR (2702, -1, -1, @len, @dbname)
  2665.         return 1
  2666.     end
  2667.     dbcc dbrepair(@dbname, dropdb)
  2668.     return 0
  2669. go
  2670.  
  2671. sp_configure updat, 0
  2672. go
  2673. reconfigure with override
  2674. go
  2675.  
  2676. /* End sp_MSkilldb */
  2677.  
  2678. /*******************************************************************************/
  2679. print N''
  2680. print N'Creating sp_MSobjectprivs'
  2681. print N''
  2682. go
  2683.  
  2684. create proc sp_MSobjectprivs
  2685.     @objname nvarchar(776) = null,
  2686.     @mode nvarchar(10) = N'object',    
  2687.     @objid int = null,                
  2688.     @srvpriv int = null,            
  2689.     @prottype int = null,            
  2690.     @grantee nvarchar(258) = null,        
  2691.    @flags int = 0,
  2692.    @rollup int = 0
  2693. as
  2694.  
  2695.     create table #objs(
  2696.         id  int NOT NULL
  2697.     )
  2698.  
  2699.     /* Temp table will hold output for final select */
  2700.     create table #output (
  2701.         action      int  NOT NULL,
  2702.         colid       int  NULL,
  2703.         uid         int  NOT NULL,
  2704.         protecttype int  NOT NULL,
  2705.         id          int  NOT NULL,
  2706.         grantor     int
  2707.     )
  2708.  
  2709.     create table #tmp(
  2710.         action   int   NOT NULL,
  2711.         uid      int   NOT NULL,
  2712.         protecttype int  NOT NULL,
  2713.     )
  2714.  
  2715.    /* mode    : 'object', 'user' or 'column'*/
  2716.    /*
  2717.     * Note:  This was expanded for 6.5 due to changes in sysprotects.columns usage, affecting
  2718.     * CPermission::ListPrivilegeColumns.  The following additional parameters are for this.
  2719.     */
  2720.    /* objid   : ID of the object we're querying */
  2721.    /* srvpriv : privilege that we're querying for (e.g. select) */
  2722.    /* prottype: Protect type, e.g. GRANT/REVOKE */
  2723.    /* grantee : Grantee name. */
  2724.  
  2725.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  2726.    /*** sp_MSobjectprivs '%s'                                         ***/
  2727.  
  2728.    /* 8.0: mode 'column', and grantee != null, we want user column level permissions for CTable/CView::ListUserColumnPermissions */
  2729.    /*      @rollup added to indicate special rollup result set for column level permission, set to 1 to roll up */
  2730.  
  2731.     /* @flags is for daVinci */
  2732.     if (@flags is null)
  2733.         select @flags = 0
  2734.  
  2735.     /* If @objid is not null, this is for the new query for perm cols. */
  2736.     if (@objid is not null) begin
  2737.         select u.name, o.name, a = col_name(p.id, a.number), a.low, a.high, a.number
  2738.             from master.dbo.spt_values a, dbo.sysprotects p, dbo.sysobjects o, dbo.sysusers u
  2739.             where p.id = @objid and p.action = @srvpriv and p.protecttype = @prottype
  2740.             and p.uid = user_id(@grantee)
  2741.             and p.columns != 0x01 and o.id = p.id and u.uid = o.uid
  2742.                 and convert(tinyint, substring(isnull(p.columns, 0x01), a.low, 1)) &
  2743.                     -- 6.5 changed so that the bit 0 position is an "invert the bits" indicator:
  2744.                     --        when 0, behaviour is the same as in prior versions, and other bits
  2745.                     --            indicate columns with the specified privilege
  2746.                     --        when 1, the other bits are indicate columns lacking the specified privilege
  2747.                     a.high <> (case when (substring(isnull(p.columns, 0x00), 1, 1) & 1 = 0) then 0 else a.high end)
  2748.                     and col_name(p.id, a.number) is not null
  2749.                     and a.type = N'P' and a.number <= (select count(*) from dbo.syscolumns where id = @objid) order by a
  2750.         return 0
  2751.     end
  2752.  
  2753.     set nocount on
  2754.  
  2755.     /*
  2756.      * To get around a 4.21 subquery bug where returning count(*) of 0 (for proc cols)
  2757.      * causes the result set to return no rows, we need two passes; one to get the
  2758.      * objects, and another to explicitly use a value (@cols) instead of a subquery.
  2759.      */
  2760.     declare @id int, @uid int, @cols int
  2761.     select @id = null, @uid = null
  2762.     if (@mode like N'us%') begin
  2763.        select @uid = user_id(@objname)
  2764.    end else if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  2765.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  2766.       select @uid = user_id(@grantee)
  2767.     end else begin
  2768.       select @id = object_id(@objname)
  2769.    end
  2770.     if (@id is null and @uid is null) begin
  2771.         RAISERROR (15001, -1, -1, @objname)
  2772.         return 1
  2773.     end
  2774.  
  2775.     /* Get a temp list of objects we're interested in.  Do not include repl_* users. */
  2776.    /* This is the original code */
  2777.    insert #objs select distinct p.id from dbo.sysprotects p
  2778.        where (@id is null or p.id = @id)
  2779.           and (@uid is null or p.uid = @uid)
  2780.        and p.action in (193, 195, 196, 197, 224, 26) and p.uid not in (16382, 16383)
  2781.  
  2782.     /* Use a "fake cursor" by deleting successive id's from #objs, as this must run on 4.21 */
  2783.     select @id = min(id) from #objs
  2784.     while (@id is not null) begin
  2785.         select @cols = count(*) from dbo.syscolumns c where c.id = @id
  2786.       /* sysprotects.columns is for SELECT and UPDATE, NULL if it is INSERT or DELETE, since INSERT and DELETE can not be applied to column level */
  2787.       insert #output select p.action, (case when p.columns is null then -1 else a.number end), p.uid, p.protecttype, p.id, p.grantor
  2788.          from master.dbo.spt_values a, dbo.sysprotects p
  2789.          where convert(tinyint, substring( isnull(p.columns, 0x01), a.low, 1)) & a.high !=0
  2790.          and (p.id = @id)
  2791.          and (@uid is null or p.uid = @uid)
  2792.          and a.number <= @cols
  2793.          and a.type = N'P'
  2794.  
  2795.       declare @count int, @whataction int, @whatid int, @dup int, @whatprot int
  2796.  
  2797.       /* First pass to correct duplicates */
  2798.       select @count = count(*) from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  2799.       if ( @count > 0 ) begin
  2800.          /* We might have duplicate rows for permission on single coulmn(s) at this point */
  2801.          /* Use a fake cursor to remove the duplicates first. */
  2802.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  2803.          select @whataction = min(action) from #tmp
  2804.          select @whatid = uid from #tmp where action = @whataction
  2805.          while (@whataction is not null) begin
  2806.             if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  2807.                /* Special case for column level permissions on ALL objects for the specified user, we don't want the row(s) on the entire table */
  2808.                /* and we don't want the possible duplicate rows in single column(s) */
  2809.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  2810.                       and (exists (select * from #output where (@whatid = uid) and (colid in (0, -1)) and action = @whataction) and (id = @id))
  2811.                delete #output where (@whatid = uid) and (colid in (0, -1)) and (action = @whataction) and (id = @id)
  2812.             end else if (@mode like N'use%') and (@objname is not null) begin
  2813.                /* Special case for the user mode, we do want to keep the entire table permissions */
  2814.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction and (id = @id)
  2815.             end else begin
  2816.                /* Other cases */
  2817.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  2818.             end
  2819.  
  2820.             delete #tmp where @whatid = uid
  2821.             select @whataction = min(action) from #tmp
  2822.             select @whatid = uid from #tmp where action = @whataction
  2823.          end
  2824.          delete #tmp
  2825.       end
  2826.  
  2827.       /* Second pass to correct protect type */
  2828.       select @count = count(*) from #output where id = @id and colid in (0, -1)
  2829.       if ( @count > 0 ) begin
  2830.          /* use another fake cursor to correct the protecttype */
  2831.          /* if there are multiple rows in #output for the same id and action, and if colid = 0 exist */
  2832.          /* then other rows should have different protecttype from the one in colid = 0 row */
  2833.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1)
  2834.          select @whataction = min(action) from #tmp
  2835.          select @whatid = uid from #tmp where action = @whataction
  2836.          select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  2837.          while (@whataction is not null) begin
  2838.                delete #output where id = @id and colid not in (0, -1) and @whataction = action and @whatid = uid and @whatprot = protecttype
  2839.                delete #tmp where action = @whataction and @whatid = uid
  2840.                select @whataction = min(action) from #tmp
  2841.                select @whatid = uid from #tmp where action = @whataction
  2842.                select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  2843.          end
  2844.          delete #tmp
  2845.       end
  2846.  
  2847.         /* Increment our "fake cursor" column and get the next one. */
  2848.         delete #objs where id = @id
  2849.         select @id = min(id) from #objs
  2850.     end
  2851.  
  2852.     /*
  2853.      * Organize so that the non-collist privileges are returned first.. this allows
  2854.      * scripting to combine them.  sysprotects.action is tinyint, so the hibyte won't conflict.
  2855.      */
  2856.  
  2857.     update #output set action = action | 0x10000000 where colid <> 0
  2858.  
  2859.     /*
  2860.      *  BUG 58252  
  2861.      *  Delete the columns that was droped
  2862.      */
  2863.     delete from #output where colid not in (0, -1) and col_name(id, colid) is null
  2864.     /*
  2865.      * Order output by uid so Public will script before other groups (we need to script privs for public before
  2866.      * other groups, before users; otherwise sysprotects doesn't hold onto things right).  Sub-order is by object id
  2867.      * so we know when we're done with one object and onto the next, then by protecttype to group all GRANTs and
  2868.      * REVOKEs together, and lastly by action (including ORDER_ACTION_BIT so scripting can be more efficient)
  2869.      * because we may have multiple rows for columns.
  2870.      */
  2871.  
  2872.     set nocount off
  2873.    if (@mode not like N'col%') begin
  2874.       /* Mode is not 'column', do the regular stuff */
  2875.        select p.action & ~convert(int, 0x10000000), N'column' = col_name(p.id, p.colid), p.uid, N'username' = user_name(p.uid),
  2876.                p.protecttype, o.name, N'owner' = user_name(o.uid), p.id, N'grantor' = user_name(p.grantor)
  2877.              from #output p, dbo.sysobjects o
  2878.              where o.id = p.id
  2879.              order by p.uid, p.id, p.protecttype, p.action
  2880.    end else
  2881.    /* Below are spcial cases for column level permissions */
  2882.    if (@objname is null) and (@grantee is not null) and (@rollup = 0) begin
  2883.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  2884.       select N'ObjectName' = o.name, N'Owner' = user_name(o.uid), N'ColumnName' = col_name(p.id, p.colid), o.sysstat & 0x0f, p.id,
  2885.              p.action & ~convert(int, 0x10000000), p.protecttype
  2886.              from #output p, dbo.sysobjects o
  2887.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  2888.              order by p.uid, p.id, p.protecttype, p.action
  2889.     end else if (@objname is not null) and (@grantee is not null) and (@rollup = 0) begin
  2890.       /* 8.0, mode 'column', and grantee != null, we want column level permissions on this object for this user */
  2891.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  2892.              p.action & ~convert(int, 0x10000000), p.protecttype
  2893.              from #output p, dbo.sysobjects o
  2894.              where o.id = p.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  2895.              order by p.uid, p.id, p.protecttype, p.action
  2896.    end else if (@objname is not null) and (@grantee is null) and (@rollup = 0) begin
  2897.       /* 8.0, mode 'column', and grantee = null, we want column level permissions on this object for all users */
  2898.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  2899.              p.action & ~convert(int, 0x10000000), p.protecttype
  2900.              from #output p, dbo.sysobjects o
  2901.              where o.id = p.id and col_name(p.id, p.colid) is not null
  2902.              order by p.uid, p.id, p.protecttype, p.action
  2903.    end else if (@objname is null) and (@grantee is not null) and (@rollup <> 0) begin
  2904.       /* 8.0, roll up version of the special path to get column level permissions from all objects on the specified user */
  2905.       select distinct N'ObjectName' = o.name, N'owner' = user_name(o.uid),
  2906.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  2907.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  2908.              N'Type' = p.protecttype
  2909.              from #output p, dbo.sysobjects o
  2910.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  2911.              order by o.name
  2912.    end else if (@objname is not null) and (@grantee is null) and (@rollup <> 0) begin
  2913.       /* 8.0, roll up version of the special path to return column level permissions on this object for all users */
  2914.       select distinct N'UserName' = user_name(p.uid),
  2915.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  2916.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  2917.              N'Type' = p.protecttype
  2918.              from #output p, dbo.sysobjects o
  2919.              where o.id = p.id and col_name(p.id, p.colid) is not null
  2920.              order by user_name(p.uid)
  2921.    end else begin
  2922.       raiserror 55555 N'Invalid parameter combinations.'
  2923.         return 1
  2924.    end
  2925. go
  2926. /* End sp_MSobjectprivs */
  2927.  
  2928.  
  2929. /*******************************************************************************/
  2930. /* Need to create the version proc here so we can set its category bit */
  2931. print N''
  2932. print N'Creating sp_MSSQLDMO70_version'
  2933. print N''
  2934. go
  2935.  
  2936. create procedure sp_MSSQLDMO70_version
  2937. as
  2938.     /* Values for this are same as @@microsoft_version:  0xrraaiibb (reserved, major, minor, build). */
  2939.     declare @i int
  2940.     select @i = 0x07000000    /* Must be in hex! */
  2941.     /* Select the numeric value, and a conversion to make it readable */
  2942.     select N'Microsoft SQLDMO Scripts' = @i, N'Version' = convert(binary(4), @i)
  2943. go
  2944.  
  2945. /*
  2946.  * The following two scripts must retain the SQLOLE nomenclature as we provide them to be an informative
  2947.  * notification to downlevel connections.
  2948.  */
  2949. create procedure sp_MSSQLOLE65_version
  2950. as
  2951.     RAISERROR 55555 N'You must upgrade your SQL Enterprise Manager and SQL-DMO (SQLOLE) to version 7.0 (SQLDMO) to connect to this server.'
  2952.    return 1
  2953. go
  2954.  
  2955. create procedure sp_MSSQLOLE_version
  2956. as
  2957.     RAISERROR 55555 N'You must upgrade your SQL Enterprise Manager and SQL-DMO (SQLOLE) to version 7.0 (SQLDMO) to connect to this server.'
  2958.    return 1
  2959. go
  2960.  
  2961. /*******************************************************************************/
  2962. print N''
  2963. print N'Creating sp_MSscriptdatabase'
  2964. print N''
  2965. go
  2966. create procedure sp_MSscriptdatabase
  2967. @dbname nvarchar(258)
  2968. as
  2969.    /* verify */
  2970.    declare @id int
  2971.    select @id = dbid from master..sysdatabases where name = @dbname
  2972.    if (@id is null)
  2973.    begin
  2974.       RAISERROR (15001, -1, -1, @dbname)
  2975.       return 1
  2976.    end
  2977.  
  2978.    /* Ready to get to work */
  2979.    declare @dbTempname nvarchar(258)
  2980.    SELECT @dbTempname = REPLACE(@dbname, N']', N']]')
  2981.    exec (N'[' + @dbTempname + N']' + N'..sp_MSscriptdb_worker ')
  2982. go
  2983. /* End sp_MSscriptdatabase */
  2984.  
  2985. /*******************************************************************************/
  2986. print N''
  2987. print N'Creating sp_MSscriptdb_worker'
  2988. print N''
  2989. go
  2990. create procedure sp_MSscriptdb_worker
  2991. as
  2992.     set nocount on
  2993.  
  2994.    declare @PageSize int;
  2995.    select @PageSize = (low/1024) from master..spt_values where number = 1 and type = N'E'
  2996.  
  2997.     create table #tempFG
  2998.     (
  2999.      cDefault     int,                                  /* 1 for default FG, 0 for user defined */
  3000.      cDBFile      int,                                  /* 1 for DB file, 0 for Log file */
  3001.       cSize        int,                                  /* in 8K page */
  3002.       cMaxSize     int,
  3003.       cGrowth      int,
  3004.      cGrowthType  int,                                  /* 1 for GrowthInMB, 0 for GrowthInPercent */
  3005.      cFGName      nvarchar(132) NOT NULL,      /* FG name */
  3006.       cName        nchar(132) NOT NULL,         /* Logical */
  3007.       cFileName    nchar(264) NOT NULL,        /* Physical */
  3008.     )
  3009.  
  3010.    /* Default FileGroup first, which should cover all the log files */
  3011.    /* This one to pick up all the db files in Primary file group, while group id = 1 */
  3012.    insert #tempFG select 1, 1, (o.size * @PageSize)/1024, (case when (o.maxsize < 1) then o.maxsize else (o.maxsize * @PageSize)/1024 end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), g.groupname, o.name, o.filename from sysfiles o, sysfilegroups g where g.groupid = 1 and g.groupid = o.groupid and (o.status & 0x40) = 0
  3013.    /* This one to pick up all the log files in Primary file group, while group id = 0, note that group id 0 does not exist in sysfilegroups */
  3014.    insert #tempFG select 1, 0, (o.size * @PageSize)/1024, (case when (o.maxsize < 1) then o.maxsize else (o.maxsize * @PageSize)/1024 end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), N'PRIMARY', o.name, o.filename from sysfiles o where o.groupid = 0 and (o.status & 0x40) <> 0
  3015.    /* Other FileGroups, we should have DBFiles, no log files */
  3016.  
  3017.     create table #tempID
  3018.    (
  3019.         cGroupID int
  3020.     )
  3021.    insert #tempID select groupid from sysfilegroups where groupid <> 1
  3022.  
  3023.    declare @FGid int
  3024.     exec(N'declare hC cursor global for select cGroupID from #tempID')
  3025.     open hC
  3026.     fetch hC into @FGid
  3027.     while (@@fetch_status >= 0) begin
  3028.       insert #tempFG select 0, 1, (o.size * @PageSize)/1024, (case when (o.maxsize < 1) then o.maxsize else (o.maxsize * @PageSize)/1024 end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), g.groupname, o.name, o.filename from sysfiles o, sysfilegroups g where g.groupid = @FGid and g.groupid = o.groupid and (o.status & 0x40) = 0
  3029.       fetch hC into @FGid
  3030.    end
  3031.     deallocate hC
  3032.  
  3033.    select * from #tempFG
  3034.    DROP TABLE #tempFG
  3035.  
  3036. go
  3037. /* End sp_MSscriptdb_worker */
  3038.  
  3039. /*******************************************************************************/
  3040. /*******************************************************************************/
  3041. /* exec sp_MSdbuseraccess 'perm', 'dbname' -- selecting priv bit from specified db                       */
  3042. /* exec sp_MSdbuseraccess 'db', 'dbname'   -- select databases, need to change db if dbname is specified */
  3043. /* exec sp_MSdbuseraccess 'init', 'dbname' -- noop                                                       */
  3044. /*******************************************************************************/
  3045. print N''
  3046. print N'Creating sp_MSdbuseraccess'
  3047. print N''
  3048. go
  3049.  
  3050. create proc sp_MSdbuseraccess
  3051.     @mode nvarchar(10) = N'perm', @qual nvarchar(128) = N'%'
  3052. as
  3053.  
  3054.    set nocount on
  3055.  
  3056.    declare @accessbit int
  3057.     if (lower(@mode) like N'perm%') begin
  3058.       /* verify */
  3059.       declare @id int, @stat int, @inval int
  3060.       select @id = dbid, @stat = status from master..sysdatabases where name = @qual
  3061.       if (@id is null) begin
  3062.          RAISERROR (15001, -1, -1, @qual)
  3063.          return 1
  3064.       end
  3065.  
  3066.       /* Can we access this db? */
  3067.       declare @single int
  3068.       select @single = DATABASEPROPERTY( @qual, N'issingleuser' )
  3069. /*      if ((@single <> 0) or ((@stat & SQLDMODBStat_Inaccessible) <> 0)) begin  */
  3070.       if ((@single <> 0) or
  3071.          (DATABASEPROPERTY(@qual, N'isdetached') <> 0) or
  3072.          (DATABASEPROPERTY(@qual, N'isshutdown') <> 0) or
  3073.          (DATABASEPROPERTY(@qual, N'issuspect') <> 0) or
  3074.          (DATABASEPROPERTY(@qual, N'isoffline') <> 0) or
  3075.          (DATABASEPROPERTY(@qual, N'isinload') <> 0) or
  3076.          (DATABASEPROPERTY(@qual, N'isinrecovery') <> 0) or
  3077.          (DATABASEPROPERTY(@qual, N'isnotrecovered') <> 0)) begin
  3078.          select @inval = 0x80000000
  3079.          select @inval
  3080.          return 0
  3081.       end
  3082.       select @accessbit = has_dbaccess(@qual)
  3083.       if ( @accessbit <> 1) begin
  3084.          select @inval = 0x40000000
  3085.          select @inval
  3086.          return 0
  3087.       end
  3088.  
  3089.       /** OK, we can access this db, need to go to the specified database to get priv bit **/
  3090.       declare @dbTempname nvarchar(258)
  3091.       declare @tempindex int
  3092.       SELECT @dbTempname = REPLACE(@qual, N']', N']]')
  3093.       exec (N'[' + @dbTempname + N']' + N'..sp_MSdbuserpriv ')
  3094.       return 0
  3095.    end
  3096.  
  3097.    /* If 'db', we want to know if what kind of access we have to the specified databases */
  3098.    /* If we are not in master, then we are selecting single database, we want to correct role bit to save round trip */
  3099.    if (lower(@mode) like N'db%') begin
  3100.       /* Make sure we're either in master or only doing it to current db. */
  3101.       declare @dbrole int
  3102.       select @dbrole = 0x0000
  3103.  
  3104.       if (db_id() <> 1)
  3105.          select @qual = db_name()
  3106.  
  3107.       /* If dbname contains ', double it for the cursor, since cursor statement is inside of '' */
  3108.       declare @qual2 nvarchar(128)
  3109.       SELECT @qual2 = REPLACE(@qual, N'''', N'''''')
  3110.  
  3111.       /* Preprocessor won't replace within quotes so have to use str(). */
  3112.       declare @invalidlogin nvarchar(12)
  3113.       select @invalidlogin = ltrim(str(convert(int, 0x40000000), 11))
  3114.       declare @inaccessible nvarchar(12)
  3115.       select @inaccessible = ltrim(str(convert(int, 0x80000000), 11))
  3116.  
  3117.       /* We can't 'use' a database with a version below the minimum. */
  3118.       /* SQL6.0 minimum is 406; SQL65 requires 408.  SQL70 database version is 408 now, it might change later */
  3119.       declare @mindbver smallint
  3120.       if (@@microsoftversion >= 0x07000000)
  3121.          select @mindbver = 408
  3122.       else
  3123.          select @mindbver = 406
  3124.  
  3125.       create table #TmpDbUserProfile (
  3126.          dbid        int NOT NULL PRIMARY KEY,
  3127.          accessperms int NOT NULL
  3128.          )
  3129.  
  3130.       /* Select all matching databases -- we want an entry even for inaccessible ones. */
  3131.       declare @dbid smallint, @dbidstr nvarchar(12), @dbstat int, @dbname nvarchar(258), @dbver smallint
  3132.       declare @dbbits int, @dbbitstr nvarchar(12)
  3133.  
  3134.       /* !!! work around here, if name contains '[', LIKE operator can't find it, since LIKE operator it treating '[' as a wild char */
  3135.       /* !!! but @qual2 might be '%', then = operator does not work */
  3136.       declare @temp int
  3137.       select @tempindex = charindex(N'[', @qual2)
  3138.       if (@tempindex <> 0)
  3139.          exec(N'declare hCdbs cursor global for select name, dbid, status, version from master..sysdatabases where name = N''' + @qual2 + N'''')
  3140.       else
  3141.          exec(N'declare hCdbs cursor global for select name, dbid, status, version from master..sysdatabases where name like N''' + @qual2 + N'''')
  3142.  
  3143.       open hCdbs
  3144.  
  3145.       /* Loop for each database, and if it's accessible, recursively call ourselves to add it. */
  3146.       fetch hCdbs into @dbname, @dbid, @dbstat, @dbver
  3147.       while (@@fetch_status >= 0) begin
  3148.          /* Preprocessor won't replace within quotes so have to use str(). */
  3149.          select @dbidstr = ltrim(str(convert(int, @dbid)))
  3150.  
  3151.          /* If it's a single user db and there's an entry for it in sysprocesses who isn't us, we can't use it. */
  3152.          declare @single_lockedout int
  3153.          select @single_lockedout = DATABASEPROPERTY( @dbname, N'issingleuser' )
  3154.          if (@single_lockedout <> 0)
  3155.             select @single_lockedout = 0 where not exists
  3156.                (select * from master..sysprocesses p where dbid = @dbid and p.spid <> @@spid)
  3157.  
  3158.          /* First see if the db is accessible (not in load, recovery, offline, single-use with another user besides us, etc.) */
  3159. /*         if ((@single_lockedout <> 0) or ((@dbstat & SQLDMODBStat_Inaccessible) <> 0) or (@dbver < @mindbver)) begin   */
  3160.          if ((@single_lockedout <> 0) or
  3161.             (@dbver < @mindbver) or
  3162.             (DATABASEPROPERTY(@dbname, N'isdetached') <> 0) or
  3163.             (DATABASEPROPERTY(@dbname, N'isshutdown') <> 0) or
  3164.             (DATABASEPROPERTY(@dbname, N'issuspect') <> 0) or
  3165.             (DATABASEPROPERTY(@dbname, N'isoffline') <> 0) or
  3166.             (DATABASEPROPERTY(@dbname, N'isinload') <> 0) or
  3167.             (DATABASEPROPERTY(@dbname, N'isinrecovery') <> 0) or
  3168.             (DATABASEPROPERTY(@dbname, N'isnotrecovered') <> 0) ) begin
  3169.             /* Inaccessible, but we can set dbo if we're sa or suser_id() is db owner sid. */
  3170.             exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @inaccessible + N')')
  3171.             end
  3172.          else begin
  3173.             /* Find out whether the current user has access to the database */
  3174.             select @accessbit = has_dbaccess(@dbname)
  3175.             if ( @accessbit <> 1) begin
  3176.                exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @invalidlogin + N')')
  3177.                end
  3178.             else begin
  3179.                /* Yes, current user does have access to this database, we are not trying to get priv at this point */
  3180.                select @dbbits = 0x01ff
  3181.                select @dbbitstr = ltrim(convert(nvarchar(12), @dbbits))
  3182.                exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @dbbitstr + N')')
  3183.                end
  3184.             end
  3185.  
  3186.          fetch hCdbs into @dbname, @dbid, @dbstat, @dbver
  3187.       end /* while FETCH_SUCCESS */
  3188.       close hCdbs
  3189.       deallocate hCdbs
  3190.  
  3191.       /* 1. If on all databases, then dbrole is dummy, need to get it later */
  3192.       /* 2. Do not double the ' character(s) in database name */
  3193.       /* 3. To speed up connection, accessperms column only indicate whether the login user can access the db, it does not contain */
  3194.       /*    permission info, we will retrieve the permission info through sp_MSdbuserpriv when necessary */
  3195.       /* !!! work around here, if name contains '[', LIKE operator can't find it, since LIKE operator it treating '[' as a wild char */
  3196.       /* !!! but @qual2 might be '%', then = operator does not work */
  3197.       if (@tempindex <> 0)
  3198.          select o.name, o.version, o.crdate, suser_sname(o.sid), o.dbid, lSize = 0, NonDbo = 0, Status = o.status, spaceavail = 0,
  3199.             LogOnSepDev = 1, o.category, t.accessperms, @dbrole, DatabaseProperty(o.name, 'isfulltextenabled'), o.status2 from master..sysdatabases o left outer join #TmpDbUserProfile t on t.dbid = o.dbid where o.name = @qual order by o.name
  3200.       else
  3201.          select o.name, o.version, o.crdate, suser_sname(o.sid), o.dbid, lSize = 0, NonDbo = 0, Status = o.status, spaceavail = 0,
  3202.             LogOnSepDev = 1, o.category, t.accessperms, @dbrole, DatabaseProperty(o.name, 'isfulltextenabled'), o.status2 from master..sysdatabases o left outer join #TmpDbUserProfile t on t.dbid = o.dbid where o.name like @qual order by o.name
  3203.       DROP TABLE #TmpDbUserProfile
  3204.       return 0
  3205.    end
  3206. go
  3207. /* End sp_MSdbuseraccess */
  3208.  
  3209. /*******************************************************************************/
  3210. /*******************************************************************************/
  3211. /* exec sp_MSdbuserpriv 'serv'  -- selecting the server (master db) user profile, just create db priv, if sa, 7 */
  3212. /* exec sp_MSdbuserpriv 'role'  -- selecting role membership for current db                                     */
  3213. /* exec sp_MSdbuserpriv 'ver'   -- selectversion70                                                              */
  3214. /* exec sp_MSdbuserpriv 'perm'  -- selecting user priv bit for the current db                                   */
  3215. /*******************************************************************************/
  3216. print N''
  3217. print N'Creating sp_MSdbuserpriv'
  3218. print N''
  3219. go
  3220.  
  3221. create proc sp_MSdbuserpriv
  3222.     @mode nvarchar(10) = N'perm'
  3223. as
  3224.  
  3225. /* Order of privilege evaluation is:  user granted/revoked, then group granted/revoked, then public granted/revoked */
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.    set nocount on
  3236.    declare @bits int, @status int, @prot int
  3237.    declare @dbrole int, @dbrolestr nvarchar(12)
  3238.  
  3239.    /* If 'srv', we're selecting the server (master db) user profile - currently, just create db priv. */
  3240.    if (lower(@mode) like N'serv%')
  3241.       begin
  3242.       select @bits = 0x0000
  3243.       if (user_id() = 1 or is_srvrolemember(N'sysadmin') = 1 or is_member(N'db_owner') = 1)
  3244.          begin
  3245.          /* sa has everything */
  3246.          select @bits = 0x0007
  3247.          end
  3248.       else begin
  3249.          select @prot = null select @prot = protecttype from sysprotects where action = 203 and uid = user_id()
  3250.          if (@prot is null) select @prot = protecttype from sysprotects where action = 203 and uid = (select status from sysusers where uid = user_id())
  3251.          if (@prot is null) select @prot = protecttype from sysprotects where action = 203 and uid = user_id(N'public')
  3252.          if (@prot = 205) select @bits = @bits | 0x0002
  3253.  
  3254.          select @prot = null select @prot = protecttype from sysprotects where action = 224 and uid = user_id() and id = object_id(N'sp_addextendedproc')
  3255.          if (@prot is null) select @prot = protecttype from sysprotects where action = 224 and uid = (select status from sysusers where uid = user_id()) and id = object_id(N'sp_addextendedproc')
  3256.          if (@prot is null) select @prot = protecttype from sysprotects where action = 224 and uid = user_id(N'public') and id = object_id(N'sp_addextendedproc')
  3257.          if (@prot = 205) select @bits = @bits | 0x0004
  3258.          end
  3259.       select @bits
  3260.       return 0
  3261.       end
  3262.  
  3263.    /* If 'perm', we're selecting the current database priv and role membership for the login user. */
  3264.     if (lower(@mode) like N'role%' or lower(@mode) like N'ver%' or lower(@mode) like N'perm%')
  3265.       begin
  3266.       if (user_id() = 1 or is_srvrolemember(N'sysadmin') = 1 or is_member(N'db_owner') = 1)
  3267.          begin
  3268.          /* sa/Dbo has everything. */
  3269.          select @bits = 0x01ff
  3270.          end
  3271.       else begin
  3272.          /* Not dbo so get individual privileges */
  3273.          select @bits = 0x0000, @status = status from sysusers where uid = user_id()
  3274.          select @prot = null select @prot = protecttype from sysprotects where action = 198 and uid = user_id()
  3275.          if (@prot is null) select @prot = protecttype from sysprotects where action = 198 and uid = (select status from sysusers where uid = user_id())
  3276.          if (@prot is null) select @prot = protecttype from sysprotects where action = 198 and uid = user_id(N'public')
  3277.          if (@prot = 205) select @bits = @bits | 0x0002
  3278.  
  3279.          select @prot = null select @prot = protecttype from sysprotects where action = 207 and uid = user_id()
  3280.          if (@prot is null) select @prot = protecttype from sysprotects where action = 207 and uid = (select status from sysusers where uid = user_id())
  3281.          if (@prot is null) select @prot = protecttype from sysprotects where action = 207 and uid = user_id(N'public')
  3282.          if (@prot = 205) select @bits = @bits | 0x0004
  3283.  
  3284.          select @prot = null select @prot = protecttype from sysprotects where action = 222 and uid = user_id()
  3285.          if (@prot is null) select @prot = protecttype from sysprotects where action = 222 and uid = (select status from sysusers where uid = user_id())
  3286.          if (@prot is null) select @prot = protecttype from sysprotects where action = 222 and uid = user_id(N'public')
  3287.          if (@prot = 205) select @bits = @bits | 0x0008
  3288.  
  3289.          select @prot = null select @prot = protecttype from sysprotects where action = 228 and uid = user_id()
  3290.          if (@prot is null) select @prot = protecttype from sysprotects where action = 228 and uid = (select status from sysusers where uid = user_id())
  3291.          if (@prot is null) select @prot = protecttype from sysprotects where action = 228 and uid = user_id(N'public')
  3292.          if (@prot = 205) select @bits = @bits | 0x0010
  3293.  
  3294.          select @prot = null select @prot = protecttype from sysprotects where action = 233 and uid = user_id()
  3295.          if (@prot is null) select @prot = protecttype from sysprotects where action = 233 and uid = (select status from sysusers where uid = user_id())
  3296.          if (@prot is null) select @prot = protecttype from sysprotects where action = 233 and uid = user_id(N'public')
  3297.          if (@prot = 205) select @bits = @bits | 0x0020
  3298.  
  3299.          select @prot = null select @prot = protecttype from sysprotects where action = 235 and uid = user_id()
  3300.          if (@prot is null) select @prot = protecttype from sysprotects where action = 235 and uid = (select status from sysusers where uid = user_id())
  3301.          if (@prot is null) select @prot = protecttype from sysprotects where action = 235 and uid = user_id(N'public')
  3302.          if (@prot = 205) select @bits = @bits | 0x0040
  3303.  
  3304.          select @prot = null select @prot = protecttype from sysprotects where action = 236 and uid = user_id()
  3305.          if (@prot is null) select @prot = protecttype from sysprotects where action = 236 and uid = (select status from sysusers where uid = user_id())
  3306.          if (@prot is null) select @prot = protecttype from sysprotects where action = 236 and uid = user_id(N'public')
  3307.          if (@prot = 205) select @bits = @bits | 0x0080
  3308.  
  3309.          select @prot = null select @prot = protecttype from sysprotects where action = 57 and uid = user_id()
  3310.          if (@prot is null) select @prot = protecttype from sysprotects where action = 57 and uid = (select status from sysusers where uid = user_id())
  3311.          if (@prot is null) select @prot = protecttype from sysprotects where action = 57 and uid = user_id(N'public')
  3312.          if (@prot = 205) select @bits = @bits | 0x0100
  3313.          end
  3314.  
  3315.       /* Get both Server and Database Role information */
  3316.       select @dbrole = 0x0000
  3317.       /* Server Roles */
  3318.       select @dbrole = (case when (is_srvrolemember(N'dbcreator') = 1) then @dbrole | 0x0001 else @dbrole end),
  3319.              @dbrole = (case when (is_srvrolemember(N'diskadmin') = 1) then @dbrole | 0x0002 else @dbrole end),
  3320.              @dbrole = (case when (is_srvrolemember(N'processadmin') = 1) then @dbrole | 0x0004 else @dbrole end),
  3321.              @dbrole = (case when (is_srvrolemember(N'securityadmin') = 1) then @dbrole | 0x0008 else @dbrole end),
  3322.              @dbrole = (case when (is_srvrolemember(N'serveradmin') = 1) then @dbrole | 0x0010 else @dbrole end),
  3323.              @dbrole = (case when (is_srvrolemember(N'setupadmin') = 1) then @dbrole | 0x0020 else @dbrole end),
  3324.              @dbrole = (case when (is_srvrolemember(N'sysadmin') = 1) then @dbrole | 0x0040 else @dbrole end),
  3325.       /* Database Roles */
  3326.              @dbrole = (case when (is_member(N'db_accessadmin') = 1) then @dbrole | 0x0080 else @dbrole end),
  3327.              @dbrole = (case when (is_member(N'db_datareader') = 1) then @dbrole | 0x0100 else @dbrole end),
  3328.              @dbrole = (case when (is_member(N'db_ddladmin') = 1) then @dbrole | 0x0200 else @dbrole end),
  3329.              @dbrole = (case when (is_member(N'db_denydatareader') = 1) then @dbrole | 0x0400 else @dbrole end),
  3330.              @dbrole = (case when (is_member(N'db_denydatawriter') = 1) then @dbrole | 0x0800 else @dbrole end),
  3331.              @dbrole = (case when (is_member(N'db_backupoperator') = 1) then @dbrole | 0x1000 else @dbrole end),
  3332.              @dbrole = (case when (is_member(N'db_owner') = 1) then @dbrole | 0x2000 else @dbrole end),
  3333.              @dbrole = (case when (is_member(N'db_securityadmin') = 1) then @dbrole | 0x4000 else @dbrole end),
  3334.              @dbrole = (case when (is_member(N'db_datawriter') = 1) then @dbrole | 0x8000 else @dbrole end)
  3335.  
  3336.       if (lower(@mode) like N'ver%')
  3337.          begin
  3338.          select @@version, N'login_id' = convert(int, suser_sid()), N'pagesize' = v.low, N'highbit' = v2.low, N'highbyte' = v3.low,
  3339.             N'casesens' = (case when (N'A' != N'a') then 1 else 0 end), @@spid, @@servername, is_srvrolemember(N'sysadmin'), @dbrole
  3340.             from master..spt_values v,master..spt_values v2,master..spt_values v3 where v.number=1 and v.type=N'E' and v2.number=2
  3341.             and v2.type=N'E' and v3.number=3 and v3.type=N'E'
  3342.          end
  3343.       else if (lower(@mode) like N'role%')
  3344.          begin
  3345.          select @dbrole
  3346.          end
  3347.       else if (lower(@mode) like N'perm%')
  3348.          begin
  3349.          select @bits
  3350.          end
  3351.       return 0
  3352.       end
  3353. go
  3354. /* End sp_MSdbuserpriv */
  3355.  
  3356.  
  3357. /*******************************************************************************/
  3358. print N''
  3359. print N'Creating sp_MShelpfulltextindex'
  3360. print N''
  3361. go
  3362.  
  3363. create proc sp_MShelpfulltextindex
  3364.    @tablename nvarchar(517)
  3365. as
  3366.    set nocount on
  3367.  
  3368.     create table #sphelpft
  3369.       (
  3370.          ind_name   nvarchar(128) NOT NULL,
  3371.       col1       nvarchar(128),
  3372.       col2       nvarchar(128),
  3373.       col3       nvarchar(128),
  3374.       col4       nvarchar(128),
  3375.       col5       nvarchar(128),
  3376.       col6       nvarchar(128),
  3377.       col7       nvarchar(128),
  3378.       col8       nvarchar(128),
  3379.       col9       nvarchar(128),
  3380.       col10      nvarchar(128),
  3381.       col11      nvarchar(128),
  3382.       col12      nvarchar(128),
  3383.       col13      nvarchar(128),
  3384.       col14      nvarchar(128),
  3385.       col15      nvarchar(128),
  3386.       col16      nvarchar(128)
  3387.       )
  3388.  
  3389.    /* all the possible full text unique indexes */
  3390.    declare @objid int
  3391.    select @objid = object_id(@tablename, N'local')
  3392.       insert #sphelpft
  3393.          select i.name,
  3394.          columnproperty( @objid, index_col(@tablename, i.indid, 1), N'AllowsNull'),
  3395.          columnproperty( @objid, index_col(@tablename, i.indid, 2), N'AllowsNull'),
  3396.          columnproperty( @objid, index_col(@tablename, i.indid, 3), N'AllowsNull'),
  3397.          columnproperty( @objid, index_col(@tablename, i.indid, 4), N'AllowsNull'),
  3398.          columnproperty( @objid, index_col(@tablename, i.indid, 5), N'AllowsNull'),
  3399.          columnproperty( @objid, index_col(@tablename, i.indid, 6), N'AllowsNull'),
  3400.          columnproperty( @objid, index_col(@tablename, i.indid, 7), N'AllowsNull'),
  3401.          columnproperty( @objid, index_col(@tablename, i.indid, 8), N'AllowsNull'),
  3402.          columnproperty( @objid, index_col(@tablename, i.indid, 9), N'AllowsNull'),
  3403.          columnproperty( @objid, index_col(@tablename, i.indid, 10), N'AllowsNull'),
  3404.          columnproperty( @objid, index_col(@tablename, i.indid, 11), N'AllowsNull'),
  3405.          columnproperty( @objid, index_col(@tablename, i.indid, 12), N'AllowsNull'),
  3406.          columnproperty( @objid, index_col(@tablename, i.indid, 13), N'AllowsNull'),
  3407.          columnproperty( @objid, index_col(@tablename, i.indid, 14), N'AllowsNull'),
  3408.          columnproperty( @objid, index_col(@tablename, i.indid, 15), N'AllowsNull'),
  3409.          columnproperty( @objid, index_col(@tablename, i.indid, 16), N'AllowsNull')
  3410.          from sysindexes i where
  3411.          @objid = i.id and
  3412.          IndexProperty(@objid, i.name, N'IsUnique') = 1 and
  3413.          IndexProperty(@objid, i.name, N'UserKeyCount') = 1 and
  3414.          /* 450 byte MAX */
  3415.          exists (select * from syscolumns where id = @objid and name = Index_col(@tablename, IndexProperty(@objid, i.name, N'IndexId'), 1)
  3416.                  and length <= 450)
  3417.  
  3418.    /* Now we need to filter out the indexes which the associated key(s) are nullable */
  3419.    /* Each index can have up to 16 associated keys, all of them need to be non-nullalbe for the index to be qualified as a full text index */
  3420.    delete #sphelpft where col1 = 1 or col2 = 1 or col3 = 1 or col4 = 1 or col5 = 1 or col6 = 1 or col7 = 1 or col8 = 1 or
  3421.                           col9 = 1 or col10 = 1 or col11 = 1 or col12 = 1 or col13 = 1 or col14 = 1 or col15 = 1 or col16 = 1
  3422.  
  3423.    select ind_name from #sphelpft
  3424.    DROP TABLE #sphelpft
  3425.  
  3426. go
  3427. /* End sp_MShelpfulltextindex */
  3428.  
  3429. /*******************************************************************************/
  3430. print N''
  3431. print N'Creating sp_MShelpfulltextscript'
  3432. print N''
  3433. go
  3434.  
  3435. create proc sp_MShelpfulltextscript
  3436.    @tablename nvarchar(517)
  3437. as
  3438.    set nocount on
  3439.  
  3440.     declare @objid int
  3441.     select @objid = object_id(@tablename)
  3442.     if (@objid is null)
  3443.     begin
  3444.         RAISERROR (15001, -1, -1, @tablename)
  3445.         return 1
  3446.     end
  3447.  
  3448.    /* prepare the information for fulltext index scripting */
  3449.    declare @activate    int
  3450.    select @activate = OBJECTPROPERTY(@objid, N'TableFulltextCatalogId')
  3451.     if (@activate <> 0)
  3452.       begin
  3453.       declare @uniqueindex nvarchar(128)
  3454.       declare @catname     nvarchar(128)
  3455.  
  3456.       /* get unique index name */
  3457.       select @uniqueindex = i.name from sysindexes i where @objid = i.id and IndexProperty(@objid, i.name, N'IsFulltextKey') = 1
  3458.       /* get catalog name */
  3459.       select @catname = f.name from sysfulltextcatalogs f, sysobjects o where f.ftcatid = o.ftcatid and o.id = @objid
  3460.       if (@uniqueindex is not null and @catname is not null)
  3461.          begin
  3462.          /* is this table fulltext index activated? */
  3463.          select @activate = OBJECTPROPERTY(@objid, N'TableHasActiveFulltextIndex')
  3464.          select @uniqueindex, @catname, @activate
  3465.          end
  3466.       end
  3467.  
  3468. go
  3469. /* End sp_MShelpfulltextscript */
  3470.  
  3471.  
  3472. /********************* Grant privileges *********************************/
  3473. print N''
  3474. print N'Granting execute permissions on procedures'
  3475. print N''
  3476. go
  3477.  
  3478. /**  Mark all the SPs as system objects **/
  3479. exec sp_MS_marksystemobject sp_MShelpcolumns
  3480. go
  3481. exec sp_MS_marksystemobject sp_MShelpindex
  3482. go
  3483. exec sp_MS_marksystemobject sp_MShelptype
  3484. go
  3485. exec sp_MS_marksystemobject sp_MSdependencies
  3486. go
  3487. exec sp_MS_marksystemobject sp_MStablespace
  3488. go
  3489. exec sp_MS_marksystemobject sp_MSindexspace
  3490. go
  3491. exec sp_MS_marksystemobject sp_MStablerefs
  3492. go
  3493. exec sp_MS_marksystemobject sp_MStablekeys
  3494. go
  3495. exec sp_MS_marksystemobject sp_MStablechecks
  3496. go
  3497. exec sp_MS_marksystemobject sp_MSsettopology
  3498. go
  3499. exec sp_MS_marksystemobject sp_MSmatchkey
  3500. go
  3501. exec sp_MS_marksystemobject sp_MSforeach_worker
  3502. go
  3503. exec sp_MS_marksystemobject sp_MSforeachdb
  3504. go
  3505. exec sp_MS_marksystemobject sp_MSforeachtable
  3506. go
  3507. exec sp_MS_marksystemobject sp_MSloginmappings
  3508. go
  3509. exec sp_MS_marksystemobject sp_MSuniquename
  3510. go
  3511. exec sp_MS_marksystemobject sp_MSkilldb
  3512. go
  3513. exec sp_MS_marksystemobject sp_MSobjectprivs
  3514. go
  3515. exec sp_MS_marksystemobject sp_MSSQLDMO70_version
  3516. go
  3517. exec sp_MS_marksystemobject sp_MSSQLOLE65_version
  3518. go
  3519. exec sp_MS_marksystemobject sp_MSSQLOLE_version
  3520. go
  3521. exec sp_MS_marksystemobject sp_MSscriptdatabase
  3522. go
  3523. exec sp_MS_marksystemobject sp_MSscriptdb_worker
  3524. go
  3525. exec sp_MS_marksystemobject sp_MSdbuseraccess
  3526. go
  3527. exec sp_MS_marksystemobject sp_MSdbuserpriv
  3528. go
  3529. exec sp_MS_marksystemobject sp_MShelpfulltextindex
  3530. go
  3531. exec sp_MS_marksystemobject sp_MShelpfulltextscript
  3532. go
  3533.  
  3534. grant execute on sp_MShelpcolumns to public
  3535. grant execute on sp_MShelpindex to public
  3536. grant execute on sp_MShelptype to public
  3537. grant execute on sp_MSdependencies to public
  3538. grant execute on sp_MStablespace to public
  3539. grant execute on sp_MSindexspace to public
  3540. grant execute on sp_MSuniquename to public
  3541. grant execute on sp_MSkilldb to public
  3542. grant execute on sp_MSobjectprivs to public
  3543. grant execute on sp_MSloginmappings to public
  3544. grant execute on sp_MStablekeys to public
  3545. grant execute on sp_MStablechecks to public
  3546. grant execute on sp_MStablerefs to public
  3547. grant execute on sp_MSsettopology to public
  3548. grant execute on sp_MSmatchkey to public
  3549. grant execute on sp_MSforeachdb to public
  3550. grant execute on sp_MSforeachtable to public
  3551. grant execute on sp_MSforeach_worker to public
  3552. grant execute on sp_MSSQLOLE_version to public
  3553. grant execute on sp_MSSQLOLE65_version to public
  3554. grant execute on sp_MSSQLDMO70_version to public
  3555. grant execute on sp_MSscriptdatabase to public
  3556. grant execute on sp_MSscriptdb_worker to public
  3557. grant execute on sp_MSdbuseraccess to public
  3558. grant execute on sp_MSdbuserpriv to public
  3559. grant execute on sp_MShelpfulltextindex to public
  3560. grant execute on sp_MShelpfulltextscript to public
  3561. go
  3562.  
  3563.  
  3564.  
  3565.  
  3566.  
  3567.  
  3568.  
  3569.  
  3570.  
  3571.  
  3572.  
  3573.  
  3574.  
  3575.  
  3576.  
  3577.  
  3578.  
  3579. /********************* Delete existing objects *********************************/
  3580. print ''
  3581. print 'Deleting existing objects...'
  3582. print ''
  3583. go
  3584.  
  3585. if exists (select * from master..sysobjects where sysstat & 0x0f = 4 and name = 'sp_MSfilterclause')
  3586.     drop procedure sp_MSfilterclause
  3587. go
  3588.  
  3589. /********************* Create new objects *********************************/
  3590.  
  3591. print ''
  3592. print 'Creating sp_MSfilterclause'
  3593. print ''
  3594. go
  3595.  
  3596. create procedure sp_MSfilterclause
  3597.     @publication nvarchar(258), @article nvarchar(258)
  3598. as
  3599.     /* Return a text column as multiple readtexts of maxcol length */
  3600.     declare @pubid int, @artid int
  3601.     select @pubid = pubid from syspublications where name = @publication
  3602.     if (@pubid is null) begin
  3603.         RAISERROR (15001, 11, -1, @publication)
  3604.         return 1
  3605.     end
  3606.     select @artid = artid from sysarticles where name = @article and pubid = @pubid
  3607.     if (@artid is null) begin
  3608.         RAISERROR (15001, 11, -1, @article)
  3609.         return 1
  3610.     end
  3611.  
  3612.     declare @val varbinary(16), @len int, @ii int, @chunk int
  3613.     -- filter clause is in unicode, the length is a half of the number of bytes.
  3614.     select @val = textptr(filter_clause), @len = datalength(filter_clause)/2 from sysarticles where artid = @artid and pubid = @pubid
  3615.     select @ii = 0, @chunk = 255
  3616.  
  3617.     /* Get all the rows of an maxcol size */
  3618.     while @len > @chunk begin
  3619.         readtext sysarticles.filter_clause @val @ii @chunk
  3620.         select @ii = @ii + @chunk, @len = @len - @chunk
  3621.     end
  3622.  
  3623.     /* Get the last chunk */
  3624.     if (@len > 0)
  3625.         readtext sysarticles.filter_clause @val @ii @len
  3626.     return 0
  3627. go
  3628. /* End sp_MSfilterclause */
  3629.  
  3630.  
  3631. /********************* Grant privileges *********************************/
  3632. print ''
  3633. print 'Granting execute permissions on procedures'
  3634. print ''
  3635. go
  3636.  
  3637. exec sp_MS_marksystemobject sp_MSfilterclause
  3638. go
  3639.  
  3640. grant execute on sp_MSfilterclause to public
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655. /********************* Delete existing objects *********************************/
  3656. print N''
  3657. print N'Deleting existing objects...'
  3658. print N''
  3659. go
  3660.  
  3661. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = 'sp_MSgetalertinfo')
  3662.     drop procedure sp_MSgetalertinfo
  3663. go
  3664. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = 'sp_MSsetalertinfo')
  3665.     drop procedure sp_MSsetalertinfo
  3666. go
  3667.  
  3668. /********************* Create new objects *********************************/
  3669.  
  3670. print N''
  3671. print N'Creating sp_MSgetalertinfo'
  3672. print N''
  3673. go
  3674. create procedure sp_MSgetalertinfo
  3675.     @includeaddresses bit = 0
  3676. as
  3677.     /* Return all alert info at one go, for performance reasons. */
  3678.     declare @FailSafeOperator nvarchar(255)
  3679.     declare @NotificationMethod int
  3680.     declare @ForwardingServer nvarchar(255)
  3681.     declare @ForwardingSeverity int
  3682.     declare @ForwardAlways int
  3683.     declare @PagerToTemplate nvarchar(255)
  3684.     declare @PagerCCTemplate nvarchar(255)
  3685.     declare @PagerSubjectTemplate nvarchar(255)
  3686.     declare @PagerSendSubjectOnly int
  3687.     declare @FailSafeEmailAddress nvarchar(255)
  3688.     declare @FailSafePagerAddress nvarchar(255)
  3689.     declare @FailSafeNetSendAddress nvarchar(255)
  3690.  
  3691.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeOperator', @param = @FailSafeOperator OUT, @no_output = N'no_output'
  3692.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertNotificationMethod', @param = @NotificationMethod OUT, @no_output = N'no_output'
  3693.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingServer', @param = @ForwardingServer OUT, @no_output = N'no_output'
  3694.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingSeverity', @param = @ForwardingSeverity OUT, @no_output = N'no_output'
  3695.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardAlways', @param = @ForwardAlways OUT, @no_output = N'no_output'
  3696.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerToTemplate', @param = @PagerToTemplate OUT, @no_output = N'no_output'
  3697.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerCCTemplate', @param = @PagerCCTemplate OUT, @no_output = N'no_output'
  3698.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSubjectTemplate', @param = @PagerSubjectTemplate OUT, @no_output = N'no_output'
  3699.     exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSendSubjectOnly', @param = @PagerSendSubjectOnly OUT, @no_output = N'no_output'
  3700.  
  3701.     if (@includeaddresses <> 0) begin
  3702.         exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeEmailAddress', @param = @FailSafeEmailAddress OUT, @no_output = N'no_output'
  3703.         exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafePagerAddress', @param = @FailSafePagerAddress OUT, @no_output = N'no_output'
  3704.         exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeNetSendAddress', @param = @FailSafeNetSendAddress OUT, @no_output = N'no_output'
  3705.     end
  3706.  
  3707.     select
  3708.         AlertFailSafeOperator = @FailSafeOperator,
  3709.         AlertNotificationMethod = @NotificationMethod,
  3710.         AlertForwardingServer = @ForwardingServer,
  3711.         AlertForwardingSeverity = @ForwardingSeverity,
  3712.         AlertPagerToTemplate = @PagerToTemplate,
  3713.         AlertPagerCCTemplate = @PagerCCTemplate,
  3714.         AlertPagerSubjectTemplate = @PagerSubjectTemplate,
  3715.         AlertPagerSendSubjectOnly = @PagerSendSubjectOnly,
  3716.         AlertForwardAlways = ISNULL(@ForwardAlways, 0)
  3717.  
  3718.     if (@includeaddresses <> 0)
  3719.         select
  3720.             AlertFailSafeEmailAddress = @FailSafeEmailAddress,
  3721.             AlertFailSafePagerAddress = @FailSafePagerAddress,
  3722.             AlertFailSafeNetSendAddress = @FailSafeNetSendAddress
  3723. go
  3724. /* End sp_MSgetalertinfo */
  3725.  
  3726. /*-----------------------------------------------------*/
  3727. /*-----------------------------------------------------*/
  3728. print N''
  3729. print N'Creating sp_MSsetalertinfo'
  3730. print N''
  3731. go
  3732. create procedure sp_MSsetalertinfo
  3733.     @failsafeoperator nvarchar(255) = null,
  3734.     @notificationmethod int = null,
  3735.     @forwardingserver nvarchar(255) = null,
  3736.     @forwardingseverity int = null,
  3737.     @pagertotemplate nvarchar(255) = null,
  3738.     @pagercctemplate nvarchar(255) = null,
  3739.     @pagersubjecttemplate nvarchar(255) = null,
  3740.     @pagersendsubjectonly int = null,
  3741.     @failsafeemailaddress nvarchar(255) = null,
  3742.     @failsafepageraddress nvarchar(255) = null,
  3743.     @failsafenetsendaddress nvarchar(255) = null,
  3744.     @forwardalways int = null -- 0 = forward only unhandled events, 1 = always forward events (both subject to @forwardingseverity)
  3745. as
  3746.     /* Set all alert info at one go, for performance reasons.  Translate values if needed. */
  3747.     if (@pagersendsubjectonly is not null and @pagersendsubjectonly <> 0)
  3748.         select @pagersendsubjectonly = 1
  3749.  
  3750.     if (@failsafeoperator is not null)
  3751.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeOperator', N'REG_SZ', @failsafeoperator
  3752.     if (@notificationmethod is not null)
  3753.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertNotificationMethod', N'REG_DWORD', @notificationmethod
  3754.     if (@forwardingserver is not null)
  3755.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingServer', N'REG_SZ', @forwardingserver
  3756.     if (@forwardingseverity is not null)
  3757.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingSeverity', N'REG_DWORD', @forwardingseverity
  3758.     if (@pagertotemplate is not null)
  3759.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerToTemplate', N'REG_SZ', @pagertotemplate
  3760.     if (@pagercctemplate is not null)
  3761.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerCCTemplate', N'REG_SZ', @pagercctemplate
  3762.     if (@pagersubjecttemplate is not null)
  3763.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSubjectTemplate', N'REG_SZ', @pagersubjecttemplate
  3764.     if (@pagersendsubjectonly is not null)
  3765.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSendSubjectOnly', N'REG_DWORD', @pagersendsubjectonly
  3766.     if (@failsafeemailaddress is not null)
  3767.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeEmailAddress', N'REG_SZ', @failsafeemailaddress
  3768.     if (@failsafepageraddress is not null)
  3769.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafePagerAddress', N'REG_SZ', @failsafepageraddress
  3770.     if (@failsafenetsendaddress is not null)
  3771.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeNetSendAddress', N'REG_SZ', @failsafenetsendaddress
  3772.     if (@forwardalways is not null)
  3773.         exec master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardAlways', N'REG_DWORD', @forwardalways
  3774. go
  3775. /* End sp_MSgetalertinfo */
  3776.  
  3777. /********************* Grant privileges *********************************/
  3778. print N''
  3779. print N'Granting execute permissions on procedures'
  3780. print N''
  3781. go
  3782.  
  3783. exec sp_MS_marksystemobject sp_MSgetalertinfo
  3784. go
  3785. exec sp_MS_marksystemobject sp_MSsetalertinfo
  3786. go
  3787.  
  3788. grant execute on sp_MSgetalertinfo to public
  3789. grant execute on sp_MSsetalertinfo to public
  3790.  
  3791.  
  3792. /********************** Verify object creation and update category bit for objects *********************************/
  3793.  
  3794.  
  3795.  
  3796.  
  3797.  
  3798. print ''
  3799. print 'Updating category for objects created by SQLDMO70.sql.'
  3800. print ''
  3801. go
  3802.  
  3803. sp_configure 'allow updates', 1
  3804. go
  3805. reconfigure with override
  3806. go
  3807.  
  3808. /* if (@@microsoftversion >= SQL70_MINVERSION) begin                                      */
  3809. /*     exec sp_MS_upd_sysobj_category 2                                                    */
  3810. /* end else begin                                                                         */
  3811. /*     RAISERROR 55555 'You need a released version of SQL 7.0 to run this SQLDMO script'  */
  3812. /* end                                                                                    */
  3813. if (@@microsoftversion < 0x07000000) begin
  3814.     RAISERROR 55555 'You need a released version of SQL 7.0 to run this SQLDMO script'
  3815. end
  3816. go
  3817.  
  3818. sp_configure 'allow updates', 0
  3819. go
  3820. reconfigure with override
  3821. go
  3822.  
  3823. if (object_id('sp_MSSQLDMO70_version') is not null) begin
  3824.     print ''
  3825.     print ''
  3826.     print ' Successful installation.'
  3827.     exec sp_MSSQLDMO70_version
  3828. end
  3829.  
  3830. /************* DUMP THE TRANSACTION LOG **************************************/
  3831. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  3832. /* script periodically, you will run out of transaction log space.           */
  3833. print ''
  3834. print 'Dumping transaction log...'
  3835. print ''
  3836. go
  3837. dump tran master with no_log
  3838. go
  3839. checkpoint
  3840. go
  3841. /************* END DUMP THE TRANSACTION LOG **********************************/
  3842.  
  3843.